]> rtime.felk.cvut.cz Git - frescor/frsh-forb.git/commitdiff
Add 'src/fna/' from commit '493e9e8be9c3761691b96e8366d036d6b3c314fb'
authorMichal Sojka <sojkam1@fel.cvut.cz>
Thu, 27 Jan 2011 13:43:13 +0000 (14:43 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Thu, 27 Jan 2011 13:43:13 +0000 (14:43 +0100)
git-subtree-dir: src/fna
git-subtree-mainline: c78e31229e23ee7fad600a405a2621d8076e3784
git-subtree-split: 493e9e8be9c3761691b96e8366d036d6b3c314fb

420 files changed:
.gitmodules [new file with mode: 0644]
README
build/.gitignore [new file with mode: 0644]
build/aquosa/.gitignore [new file with mode: 0644]
build/aquosa/Makefile [new file with mode: 0644]
build/aquosa/Makefile.omk [new file with mode: 0644]
build/aquosa/Makefile.rules [new file with mode: 0644]
build/aquosa/config.target [new file with mode: 0644]
build/aquosa/create-links [new file with mode: 0755]
build/aquosa/fna [new symlink]
build/aquosa/forb [new symlink]
build/aquosa/fosa [new symlink]
build/aquosa/frsh [new symlink]
build/aquosa/frsh-forb-demo.sh [new file with mode: 0755]
build/aquosa/frsh-include [new symlink]
build/aquosa/fwp [new symlink]
build/aquosa/kernelcfg2mk [new file with mode: 0755]
build/aquosa/ulut [new symlink]
build/aquosa/wvtest/c/Makefile [new file with mode: 0644]
build/aquosa/wvtest/c/Makefile.omk [new file with mode: 0644]
build/aquosa/wvtest/c/wvtest.c [new file with mode: 0644]
build/aquosa/wvtest/c/wvtest.h [new file with mode: 0644]
build/aquosa/wvtest/c/wvtestfrsh.c [new file with mode: 0644]
build/aquosa/wvtest/c/wvtestmain.c [new file with mode: 0644]
build/aquosa/wvtest/cpp/Makefile [new file with mode: 0644]
build/aquosa/wvtest/cpp/Makefile.omk [new file with mode: 0644]
build/aquosa/wvtest/cpp/wvtest.cc [new file with mode: 0644]
build/aquosa/wvtest/cpp/wvtest.h [new file with mode: 0644]
build/aquosa/wvtest/cpp/wvtestmain.cc [new file with mode: 0644]
build/aquosa/wvtestrun [new symlink]
build/marte/Makefile [new file with mode: 0644]
build/marte/Makefile.omk [new file with mode: 0644]
build/marte/Makefile.rules [new file with mode: 0644]
build/marte/config.target [new file with mode: 0644]
build/marte/create-links [new file with mode: 0755]
doc/RelNotes-0.1.1.txt [new file with mode: 0644]
doc/RelNotes-0.1.txt [new file with mode: 0644]
scripts/reselase.sh [new file with mode: 0755]
src/fna/COPYING [moved from COPYING with 100% similarity]
src/fna/Changelog [moved from Changelog with 100% similarity]
src/fna/INSTALL [moved from INSTALL with 100% similarity]
src/fna/Makefile [moved from Makefile with 100% similarity]
src/fna/Makefile.omk [moved from Makefile.omk with 100% similarity]
src/fna/README [new file with mode: 0644]
src/fna/TODO [moved from TODO with 100% similarity]
src/fna/config.mk_example [moved from config.mk_example with 100% similarity]
src/fna/doc/api_fna_html.tar.gz [moved from doc/api_fna_html.tar.gz with 100% similarity]
src/fna/doc/fna-refman.pdf [moved from doc/fna-refman.pdf with 100% similarity]
src/fna/include/Makefile.omk [moved from include/Makefile.omk with 100% similarity]
src/fna/include/fna.h [moved from include/fna.h with 100% similarity]
src/fna/include/fna_configuration.h [moved from include/fna_configuration.h with 100% similarity]
src/fna/include/frsh_fna.h [moved from include/frsh_fna.h with 100% similarity]
src/fna/rules.mk [moved from rules.mk with 100% similarity]
src/fna/src/Makefile [moved from src/Makefile with 100% similarity]
src/fna/src/fna_configuration.c [moved from src/fna_configuration.c with 100% similarity]
src/fna/src_frescan/Makefile [moved from src_frescan/Makefile with 100% similarity]
src/fna/src_frescan/README [moved from src_frescan/README with 100% similarity]
src/fna/src_frescan/TODO [moved from src_frescan/TODO with 100% similarity]
src/fna/src_frescan/frescan.c [moved from src_frescan/frescan.c with 100% similarity]
src/fna/src_frescan/frescan.h [moved from src_frescan/frescan.h with 100% similarity]
src/fna/src_frescan/frescan_bwres.c [moved from src_frescan/frescan_bwres.c with 100% similarity]
src/fna/src_frescan/frescan_bwres.h [moved from src_frescan/frescan_bwres.h with 100% similarity]
src/fna/src_frescan/frescan_bwres_analysis.c [moved from src_frescan/frescan_bwres_analysis.c with 100% similarity]
src/fna/src_frescan/frescan_bwres_analysis.h [moved from src_frescan/frescan_bwres_analysis.h with 100% similarity]
src/fna/src_frescan/frescan_bwres_fna.c [moved from src_frescan/frescan_bwres_fna.c with 100% similarity]
src/fna/src_frescan/frescan_bwres_fna.h [moved from src_frescan/frescan_bwres_fna.h with 100% similarity]
src/fna/src_frescan/frescan_bwres_frsh_fna.c [moved from src_frescan/frescan_bwres_frsh_fna.c with 100% similarity]
src/fna/src_frescan/frescan_bwres_messages.c [moved from src_frescan/frescan_bwres_messages.c with 100% similarity]
src/fna/src_frescan/frescan_bwres_messages.h [moved from src_frescan/frescan_bwres_messages.h with 100% similarity]
src/fna/src_frescan/frescan_bwres_mode_change.c [moved from src_frescan/frescan_bwres_mode_change.c with 100% similarity]
src/fna/src_frescan/frescan_bwres_mode_change.h [moved from src_frescan/frescan_bwres_mode_change.h with 100% similarity]
src/fna/src_frescan/frescan_bwres_requests.c [moved from src_frescan/frescan_bwres_requests.c with 100% similarity]
src/fna/src_frescan/frescan_bwres_requests.h [moved from src_frescan/frescan_bwres_requests.h with 100% similarity]
src/fna/src_frescan/frescan_bwres_robjs.c [moved from src_frescan/frescan_bwres_robjs.c with 100% similarity]
src/fna/src_frescan/frescan_bwres_robjs.h [moved from src_frescan/frescan_bwres_robjs.h with 100% similarity]
src/fna/src_frescan/frescan_bwres_threads.c [moved from src_frescan/frescan_bwres_threads.c with 100% similarity]
src/fna/src_frescan/frescan_bwres_threads.h [moved from src_frescan/frescan_bwres_threads.h with 100% similarity]
src/fna/src_frescan/frescan_config.h [moved from src_frescan/frescan_config.h with 100% similarity]
src/fna/src_frescan/frescan_data.c [moved from src_frescan/frescan_data.c with 100% similarity]
src/fna/src_frescan/frescan_data.h [moved from src_frescan/frescan_data.h with 100% similarity]
src/fna/src_frescan/frescan_debug.h [moved from src_frescan/frescan_debug.h with 100% similarity]
src/fna/src_frescan/frescan_hw_buffer.c [moved from src_frescan/frescan_hw_buffer.c with 100% similarity]
src/fna/src_frescan/frescan_hw_buffer.h [moved from src_frescan/frescan_hw_buffer.h with 100% similarity]
src/fna/src_frescan/frescan_id.c [moved from src_frescan/frescan_id.c with 100% similarity]
src/fna/src_frescan/frescan_id.h [moved from src_frescan/frescan_id.h with 100% similarity]
src/fna/src_frescan/frescan_packets.c [moved from src_frescan/frescan_packets.c with 100% similarity]
src/fna/src_frescan/frescan_packets.h [moved from src_frescan/frescan_packets.h with 100% similarity]
src/fna/src_frescan/frescan_queues.c [moved from src_frescan/frescan_queues.c with 100% similarity]
src/fna/src_frescan/frescan_queues.h [moved from src_frescan/frescan_queues.h with 100% similarity]
src/fna/src_frescan/frescan_servers.c [moved from src_frescan/frescan_servers.c with 100% similarity]
src/fna/src_frescan/frescan_servers.c_posix [moved from src_frescan/frescan_servers.c_posix with 100% similarity]
src/fna/src_frescan/frescan_servers.h [moved from src_frescan/frescan_servers.h with 100% similarity]
src/fna/src_frescan/frescan_servers_replenishments.c [moved from src_frescan/frescan_servers_replenishments.c with 100% similarity]
src/fna/src_frescan/frescan_servers_replenishments.c_posix [moved from src_frescan/frescan_servers_replenishments.c_posix with 100% similarity]
src/fna/src_frescan/frescan_servers_replenishments.h [moved from src_frescan/frescan_servers_replenishments.h with 100% similarity]
src/fna/src_frescan/frescan_types.h [moved from src_frescan/frescan_types.h with 100% similarity]
src/fna/src_rtep/Makefile [moved from src_rtep/Makefile with 100% similarity]
src/fna/src_rtep/rtep_fna.h [moved from src_rtep/rtep_fna.h with 100% similarity]
src/fna/src_rtep/rtep_fna_c.c [moved from src_rtep/rtep_fna_c.c with 100% similarity]
src/fna/src_rtep/rtep_frsh_fna_c.c [moved from src_rtep/rtep_frsh_fna_c.c with 100% similarity]
src/fna/src_unix/Makefile [moved from src_unix/Makefile with 100% similarity]
src/fna/src_unix/Makefile.omk [moved from src_unix/Makefile.omk with 100% similarity]
src/fna/src_unix/unix_fna.c [moved from src_unix/unix_fna.c with 100% similarity]
src/fna/src_unix/unix_fna.h [moved from src_unix/unix_fna.h with 100% similarity]
src/fna/tests/tests_frescan/Makefile [moved from tests/tests_frescan/Makefile with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_cancel_in_master.c [moved from tests/tests_frescan/test_frescan_bwres_cancel_in_master.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_cancel_in_slave.c [moved from tests/tests_frescan/test_frescan_bwres_cancel_in_slave.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_gn_vs_single_measures.c [moved from tests/tests_frescan/test_frescan_bwres_gn_vs_single_measures.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_init.c [moved from tests/tests_frescan/test_frescan_bwres_init.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_messages_req_gn.c [moved from tests/tests_frescan/test_frescan_bwres_messages_req_gn.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_negotiate_in_master.c [moved from tests/tests_frescan/test_frescan_bwres_negotiate_in_master.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_negotiate_in_master_not_accepted.c [moved from tests/tests_frescan/test_frescan_bwres_negotiate_in_master_not_accepted.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_negotiate_in_slave.c [moved from tests/tests_frescan/test_frescan_bwres_negotiate_in_slave.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_negotiate_in_slave_not_accepted.c [moved from tests/tests_frescan/test_frescan_bwres_negotiate_in_slave_not_accepted.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_negotiate_in_slave_with_sc.c [moved from tests/tests_frescan/test_frescan_bwres_negotiate_in_slave_with_sc.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_negotiate_in_slave_with_sc_and_mode_change.c [moved from tests/tests_frescan/test_frescan_bwres_negotiate_in_slave_with_sc_and_mode_change.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_renegotiate_in_master.c [moved from tests/tests_frescan/test_frescan_bwres_renegotiate_in_master.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_renegotiate_in_slave.c [moved from tests/tests_frescan/test_frescan_bwres_renegotiate_in_slave.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_robjs_timedwait.c [moved from tests/tests_frescan/test_frescan_bwres_robjs_timedwait.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_bwres_robjs_wait.c [moved from tests/tests_frescan/test_frescan_bwres_robjs_wait.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_fp_send_basic.c [moved from tests/tests_frescan/test_frescan_fp_send_basic.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_fp_send_basic_pp_measures.c [moved from tests/tests_frescan/test_frescan_fp_send_basic_pp_measures.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_fp_send_receive_measures.c [moved from tests/tests_frescan/test_frescan_fp_send_receive_measures.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_init.c [moved from tests/tests_frescan/test_frescan_init.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_queues.c [moved from tests/tests_frescan/test_frescan_queues.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_servers_current_budget.c [moved from tests/tests_frescan/test_frescan_servers_current_budget.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_servers_destroy.c [moved from tests/tests_frescan/test_frescan_servers_destroy.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_servers_perceived_commit.c [moved from tests/tests_frescan/test_frescan_servers_perceived_commit.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_servers_send_basic.c [moved from tests/tests_frescan/test_frescan_servers_send_basic.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_servers_send_fast.c [moved from tests/tests_frescan/test_frescan_servers_send_fast.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_servers_send_receive_measures.c [moved from tests/tests_frescan/test_frescan_servers_send_receive_measures.c with 100% similarity]
src/fna/tests/tests_frescan/test_frescan_servers_update.c [moved from tests/tests_frescan/test_frescan_servers_update.c with 100% similarity]
src/fna/tests/tests_rtep_fna/Makefile [moved from tests/tests_rtep_fna/Makefile with 100% similarity]
src/fna/tests/tests_rtep_fna/test_c_rtep_fna.c [moved from tests/tests_rtep_fna/test_c_rtep_fna.c with 100% similarity]
src/fna/tests/tests_rtep_fna/test_c_rtep_fna_measurement.c [moved from tests/tests_rtep_fna/test_c_rtep_fna_measurement.c with 100% similarity]
src/fna/tests/tests_rtep_fna/test_c_rtep_fna_with_frsh.c [moved from tests/tests_rtep_fna/test_c_rtep_fna_with_frsh.c with 100% similarity]
src/fna/tests/tests_rtep_fna/test_c_rtep_frsh_fna.c [moved from tests/tests_rtep_fna/test_c_rtep_frsh_fna.c with 100% similarity]
src/fna/tests/tests_unix_fna/Makefile [moved from tests/tests_unix_fna/Makefile with 100% similarity]
src/fna/tests/tests_unix_fna/test_unix_address.c [moved from tests/tests_unix_fna/test_unix_address.c with 100% similarity]
src/fna/tests/tests_unix_fna/test_unix_fna_send_receive.c [moved from tests/tests_unix_fna/test_unix_fna_send_receive.c with 100% similarity]
src/fna/tests/tests_unix_fna/test_unix_fna_send_receive_script [moved from tests/tests_unix_fna/test_unix_fna_send_receive_script with 100% similarity]
src/fna/tests/tests_unix_fna/test_unix_send_receive.c [moved from tests/tests_unix_fna/test_unix_send_receive.c with 100% similarity]
src/forb/.gitignore [new file with mode: 0644]
src/forb/COPYING [new file with mode: 0644]
src/forb/Doxyfile [new file with mode: 0644]
src/forb/Makefile [new file with mode: 0644]
src/forb/Makefile.omk [new file with mode: 0644]
src/forb/README [new file with mode: 0644]
src/forb/TODO [new file with mode: 0644]
src/forb/doc/forb.vpp [new file with mode: 0644]
src/forb/forb-idl/Makefile [new file with mode: 0644]
src/forb/forb-idl/Makefile.am [new file with mode: 0644]
src/forb/forb-idl/Makefile.in [new file with mode: 0644]
src/forb/forb-idl/Makefile.omk [new file with mode: 0644]
src/forb/forb-idl/Makefile.rules [new file with mode: 0644]
src/forb/forb-idl/ORBit-idl-2.0.pc.in [new file with mode: 0644]
src/forb/forb-idl/config.h [new file with mode: 0644]
src/forb/forb-idl/forb-idl-backend.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-backend.h [new file with mode: 0644]
src/forb/forb-idl/forb-idl-c-backend.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-c-backend.h [new file with mode: 0644]
src/forb/forb-idl/forb-idl-c-common.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-c-deps.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-c-headers.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-c-imodule.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-c-skelimpl.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-c-skels.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-c-stubs.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-c-typecode.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-c-utils.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-driver.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-main.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl-utils.c [new file with mode: 0644]
src/forb/forb-idl/forb-idl2.h [new file with mode: 0644]
src/forb/forb-idl/forb-idl3-types.h [new file with mode: 0644]
src/forb/forb-idl/forb_config.h [new file with mode: 0644]
src/forb/src/Makefile [new file with mode: 0644]
src/forb/src/Makefile.omk [new file with mode: 0644]
src/forb/src/basic_types.h [new file with mode: 0644]
src/forb/src/cdr.c [new file with mode: 0644]
src/forb/src/cdr.h [new file with mode: 0644]
src/forb/src/cdr_codec.h [new file with mode: 0644]
src/forb/src/daemon.c [new file with mode: 0644]
src/forb/src/discovery.c [new file with mode: 0644]
src/forb/src/discovery.h [new file with mode: 0644]
src/forb/src/exec_req.c [new file with mode: 0644]
src/forb/src/exec_req.h [new file with mode: 0644]
src/forb/src/executor.c [new file with mode: 0644]
src/forb/src/executor.h [new file with mode: 0644]
src/forb/src/forb-idl.idl [new file with mode: 0644]
src/forb/src/forb-internal.h [new file with mode: 0644]
src/forb/src/forb.c [new file with mode: 0644]
src/forb/src/forb.h [new file with mode: 0644]
src/forb/src/forb_endian.h [new file with mode: 0644]
src/forb/src/forb_utils.h [new file with mode: 0644]
src/forb/src/iop-idl.idl [new file with mode: 0644]
src/forb/src/iop.c [new file with mode: 0644]
src/forb/src/iop.h [new file with mode: 0644]
src/forb/src/object.c [new file with mode: 0644]
src/forb/src/object.h [new file with mode: 0644]
src/forb/src/object_type.h [new file with mode: 0644]
src/forb/src/peer.c [new file with mode: 0644]
src/forb/src/peer.h [new file with mode: 0644]
src/forb/src/port.c [new file with mode: 0644]
src/forb/src/port.h [new file with mode: 0644]
src/forb/src/proto.c [new file with mode: 0644]
src/forb/src/proto.h [new file with mode: 0644]
src/forb/src/proto_inet.c [new file with mode: 0644]
src/forb/src/proto_inet.h [new file with mode: 0644]
src/forb/src/proto_unix.c [new file with mode: 0644]
src/forb/src/proto_unix.h [new file with mode: 0644]
src/forb/src/refcnt.c [new file with mode: 0644]
src/forb/src/refcnt.h [new file with mode: 0644]
src/forb/src/regref.c [new file with mode: 0644]
src/forb/src/regref.h [new file with mode: 0644]
src/forb/src/request.c [new file with mode: 0644]
src/forb/src/request.h [new file with mode: 0644]
src/forb/src/server_id.h [new file with mode: 0644]
src/forb/src/sha1.c [new file with mode: 0644]
src/forb/src/sha1.h [new file with mode: 0644]
src/forb/src/syncobj.c [new file with mode: 0644]
src/forb/src/syncobj.h [new file with mode: 0644]
src/forb/src/tests/Makefile [new file with mode: 0644]
src/forb/src/tests/Makefile.omk [new file with mode: 0644]
src/forb/src/tests/discovery.c [new file with mode: 0644]
src/forb/src/tests/hello.idl [new file with mode: 0644]
src/forb/src/tests/hello_impl.c [new file with mode: 0644]
src/forb/src/tests/hello_impl.h [new file with mode: 0644]
src/forb/src/tests/hello_inproc.c [new file with mode: 0644]
src/forb/src/tests/hello_remote.c [new file with mode: 0644]
src/forb/src/tests/object_to_string/Makefile [new file with mode: 0644]
src/forb/src/tests/object_to_string/Makefile.omk [new file with mode: 0644]
src/forb/src/tests/object_to_string/interface.idl [new file with mode: 0644]
src/forb/src/tests/object_to_string/obj2str.c [new file with mode: 0644]
src/forb/src/tests/objref/Makefile [new file with mode: 0644]
src/forb/src/tests/objref/Makefile.omk [new file with mode: 0644]
src/forb/src/tests/objref/objref.c [new file with mode: 0644]
src/forb/src/tests/objref/objref.idl [new file with mode: 0644]
src/forb/src/tests/regobjref.c [new file with mode: 0644]
src/forb/src/tests/sequence.c [new file with mode: 0644]
src/forb/src/tests/sequence.idl [new file with mode: 0644]
src/forb/src/tests/test_proto_inet.c [new file with mode: 0644]
src/forb/src/tests/test_proto_unix.c [new file with mode: 0644]
src/forb/src/tests/test_syncobj.c [new file with mode: 0644]
src/forb/src/types.idl [new file with mode: 0644]
src/forb/src/ul_log_domains [new file with mode: 0755]
src/forb/src/uuid.c [new file with mode: 0644]
src/forb/src/uuid.h [new file with mode: 0644]
src/forb/tests-idl/Makefile [new file with mode: 0644]
src/forb/tests-idl/Makefile.omk [new file with mode: 0644]
src/forb/tests-idl/enum.idl [new file with mode: 0644]
src/forb/tests-idl/example_client.c [new file with mode: 0644]
src/forb/tests-idl/example_server.c [new file with mode: 0644]
src/forb/tests-idl/myinterface.idl [new file with mode: 0644]
src/forb/tests-idl/sequence.idl [new file with mode: 0644]
src/forb/tests-idl/string_test.idl [new file with mode: 0644]
src/forb/tests-idl/struct.idl [new file with mode: 0644]
src/forb/tests-idl/typedef.idl [new file with mode: 0644]
src/frsh-forb.el [new file with mode: 0644]
src/frsh-include/.cvsignore [new file with mode: 0644]
src/frsh-include/Makefile.omk [new file with mode: 0644]
src/frsh-include/dtm.h [new file with mode: 0644]
src/frsh-include/frsh.h [new file with mode: 0644]
src/frsh-include/frsh_configuration_parameters.h [new file with mode: 0644]
src/frsh-include/frsh_core.h [new file with mode: 0644]
src/frsh-include/frsh_core_types.h [new file with mode: 0644]
src/frsh-include/frsh_cpp_macros.h [new file with mode: 0644]
src/frsh-include/frsh_debug_and_trace.h [new file with mode: 0644]
src/frsh-include/frsh_debug_and_trace_types.h [new file with mode: 0644]
src/frsh-include/frsh_distributed.h [new file with mode: 0644]
src/frsh-include/frsh_distributed_types.h [new file with mode: 0644]
src/frsh-include/frsh_dynamic_reclaiming.h [new file with mode: 0644]
src/frsh-include/frsh_energy_management.h [new file with mode: 0644]
src/frsh-include/frsh_energy_management_types.h [new file with mode: 0644]
src/frsh-include/frsh_error.h [new file with mode: 0644]
src/frsh-include/frsh_feedback_control.h [new file with mode: 0644]
src/frsh-include/frsh_feedback_control_types.h [new file with mode: 0644]
src/frsh-include/frsh_hierarchical.h [new file with mode: 0644]
src/frsh-include/frsh_hierarchical_types.h [new file with mode: 0644]
src/frsh-include/frsh_implementation_specific.h [new file with mode: 0644]
src/frsh-include/frsh_implementation_specific_types.h [new file with mode: 0644]
src/frsh-include/frsh_memory_management.h [new file with mode: 0644]
src/frsh-include/frsh_opaque_types.h [new file with mode: 0644]
src/frsh-include/frsh_shared_objects.h [new file with mode: 0644]
src/frsh-include/frsh_shared_objects_types.h [new file with mode: 0644]
src/frsh-include/frsh_spare_capacity.h [new file with mode: 0644]
src/frsh-include/frsh_spare_capacity_types.h [new file with mode: 0644]
src/frsh-include/frsh_thread_attrs.h [new file with mode: 0644]
src/frsh-include/frsh_time.h [new file with mode: 0644]
src/frsh-include/frsh_time_types.h [new file with mode: 0644]
src/frsh-include/frsh_transaction.h [new file with mode: 0644]
src/fwp/.gitignore [new file with mode: 0644]
src/fwp/README [new file with mode: 0644]
src/fwp/fwp/.gitignore [new file with mode: 0644]
src/fwp/fwp/Changelog [new file with mode: 0644]
src/fwp/fwp/INSTALL [new file with mode: 0644]
src/fwp/fwp/Makefile [new file with mode: 0644]
src/fwp/fwp/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/README [new file with mode: 0644]
src/fwp/fwp/fwp-demo1 [new file with mode: 0755]
src/fwp/fwp/lib/Makefile [new file with mode: 0644]
src/fwp/fwp/lib/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/lib/frsh_fwp/Makefile [new file with mode: 0644]
src/fwp/fwp/lib/frsh_fwp/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/lib/frsh_fwp/fwp_block.c [new file with mode: 0644]
src/fwp/fwp/lib/frsh_fwp/fwp_fna.c [new file with mode: 0644]
src/fwp/fwp/lib/frsh_fwp/fwp_fna.h [new file with mode: 0644]
src/fwp/fwp/lib/frsh_fwp/fwp_fra.c [new file with mode: 0644]
src/fwp/fwp/lib/frsh_fwp/fwp_idl.idl [new file with mode: 0644]
src/fwp/fwp/lib/frsh_fwp/fwp_res.h [new file with mode: 0644]
src/fwp/fwp/lib/fwp/Doxyfile [new file with mode: 0644]
src/fwp/fwp/lib/fwp/Makefile [new file with mode: 0644]
src/fwp/fwp/lib/fwp/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp.c [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp.h [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_conf.h [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_confdefs.h [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_debug.h [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_endpoint.c [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_endpoint.h [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_msgb.c [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_msgb.h [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_msgq.c [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_msgq.h [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_types.h [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_utils.c [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_utils.h [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_vres.c [new file with mode: 0644]
src/fwp/fwp/lib/fwp/fwp_vres.h [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/Makefile [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/fwp_msgtest/Makefile [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/fwp_msgtest/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/fwp_msgtest/fwp_msgtest.c [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/fwp_prototest/Makefile [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/fwp_prototest/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/fwp_prototest/fwp_sendrecv_test1.c [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/fwp_prototest/fwp_sendrecv_test2.c [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/fwp_vrestest/Makefile [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/fwp_vrestest/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/fwp_vrestest/fwp_vrestest1.c [new file with mode: 0644]
src/fwp/fwp/lib/fwp/tests/fwp_vrestest/fwp_vrestest2.c [new file with mode: 0644]
src/fwp/fwp/mngr/Makefile [new file with mode: 0644]
src/fwp/fwp/mngr/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/mngr/fwp_admctrl.c [new file with mode: 0644]
src/fwp/fwp/mngr/fwp_admctrl.h [new file with mode: 0644]
src/fwp/fwp/mngr/fwp_mngr.c [new file with mode: 0644]
src/fwp/fwp/old.mngr/Makefile [new file with mode: 0644]
src/fwp/fwp/old.mngr/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/old.mngr/admtest_utilization.c [new file with mode: 0644]
src/fwp/fwp/old.mngr/fwp_admctrl.c [new file with mode: 0644]
src/fwp/fwp/old.mngr/fwp_admctrl.h [new file with mode: 0644]
src/fwp/fwp/old.mngr/fwp_foreach.h [new file with mode: 0644]
src/fwp/fwp/old.mngr/fwp_mngr.c [new file with mode: 0644]
src/fwp/fwp/old.mngr/fwp_participant_table.c [new file with mode: 0644]
src/fwp/fwp/old.mngr/fwp_participant_table.h [new file with mode: 0644]
src/fwp/fwp/old.mngr/gui.c [new file with mode: 0644]
src/fwp/fwp/old.mngr/gui.h [new file with mode: 0644]
src/fwp/fwp/old.mngr/tests/BE_packet_size_graph [new file with mode: 0644]
src/fwp/fwp/old.mngr/tests/Makefile [new file with mode: 0644]
src/fwp/fwp/old.mngr/tests/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/old.mngr/tests/VI_packet_size_graph [new file with mode: 0644]
src/fwp/fwp/old.mngr/tests/VO_packet_size_graph [new file with mode: 0644]
src/fwp/fwp/old.mngr/tests/adm_utilization.c [new file with mode: 0644]
src/fwp/fwp/old.mngr/tests/plot [new file with mode: 0755]
src/fwp/fwp/old.mngr/tests/plot_sat [new file with mode: 0644]
src/fwp/fwp/tests/Makefile [new file with mode: 0644]
src/fwp/fwp/tests/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/tests/README [new file with mode: 0644]
src/fwp/fwp/tests/fwp_mngrtest/Makefile [new file with mode: 0644]
src/fwp/fwp/tests/fwp_mngrtest/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/tests/fwp_mngrtest/fwp_mngrtest.c [new file with mode: 0644]
src/fwp/fwp/tests/hashtest/hashtable.h [new file with mode: 0644]
src/fwp/fwp/tests/hashtest/hashtest.c [new file with mode: 0644]
src/fwp/fwp/tests/timing/Makefile [new file with mode: 0644]
src/fwp/fwp/tests/timing/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/tests/timing/fwp-timing.c [new file with mode: 0644]
src/fwp/fwp/tests/timing/fwp-timing.gnuplot [new file with mode: 0644]
src/fwp/fwp/tests/timing/fwp-timing.pl [new file with mode: 0755]
src/fwp/fwp/tests/unixsocktest/Makefile [new file with mode: 0644]
src/fwp/fwp/tests/unixsocktest/Makefile.omk [new file with mode: 0644]
src/fwp/fwp/tests/unixsocktest/unixclient.c [new file with mode: 0644]
src/fwp/fwp/tests/unixsocktest/unixclient_thread.c [new file with mode: 0644]
src/fwp/fwp/tests/unixsocktest/unixclient_thread_dgram.c [new file with mode: 0644]
src/fwp/fwp/tests/unixsocktest/unixserver.c [new file with mode: 0644]
src/fwp/fwp/tests/unixsocktest/unixserver_dgram.c [new file with mode: 0644]
src/fwp/fwp/wme_test [new symlink]
src/fwp/patches/ac_debug.patch [new file with mode: 0644]
src/fwp/patches/ac_param_setup_24-rc2.patch [new file with mode: 0644]
src/fwp/patches/ac_param_setup_24-rc3.patch [new file with mode: 0644]
src/fwp/patches/qos_enable_24-rc3.patch [new file with mode: 0644]
src/fwp/patches/series [new file with mode: 0644]
src/fwp/wme_test/.gitignore [new file with mode: 0644]
src/fwp/wme_test/Makefile [new file with mode: 0644]
src/fwp/wme_test/Makefile.omk [new file with mode: 0644]
src/fwp/wme_test/Makefile.std [new file with mode: 0644]
src/fwp/wme_test/be_influence2/graph2 [new file with mode: 0755]
src/fwp/wme_test/be_influence2/plot2 [new file with mode: 0755]
src/fwp/wme_test/be_influence2/run [new file with mode: 0755]
src/fwp/wme_test/be_influence2/run2 [new file with mode: 0755]
src/fwp/wme_test/common.c [new file with mode: 0644]
src/fwp/wme_test/common.h [new file with mode: 0644]
src/fwp/wme_test/more_sta/plot [new file with mode: 0755]
src/fwp/wme_test/more_sta/plot-wlans [new file with mode: 0755]
src/fwp/wme_test/more_sta/run [new file with mode: 0755]
src/fwp/wme_test/more_sta/run-wlans [new file with mode: 0755]
src/fwp/wme_test/more_sta/wclientpar [new file with mode: 0755]
src/fwp/wme_test/plot [new file with mode: 0755]
src/fwp/wme_test/plot_commands [new file with mode: 0644]
src/fwp/wme_test/run [new file with mode: 0755]
src/fwp/wme_test/sat_per_packet_size/graph [new file with mode: 0755]
src/fwp/wme_test/sat_per_packet_size/run [new file with mode: 0755]
src/fwp/wme_test/sat_per_packet_size/sat-graph [new file with mode: 0755]
src/fwp/wme_test/schedlat.c [new file with mode: 0644]
src/fwp/wme_test/tester [new file with mode: 0755]
src/fwp/wme_test/wclient.c [new file with mode: 0644]
src/fwp/wme_test/wserver.c [new file with mode: 0644]
src/update-frescor-svn [new file with mode: 0755]
src/update-to-git-head [new file with mode: 0755]
src/wvtest.sh [new file with mode: 0755]

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..8802737
--- /dev/null
@@ -0,0 +1,24 @@
+[submodule "src/forb"]
+       path = src/forb
+       url = ../forb
+[submodule "src/fwp"]
+       path = src/fwp
+       url = ../fwp
+[submodule "src/ulut"]
+       path = src/ulut
+       url = git://rtime.felk.cvut.cz/ulut.git
+[submodule "src/frsh-include"]
+       path = src/frsh-include
+       url = ../frsh-include
+[submodule "src/fna"]
+       path = src/fna
+       url = ../fna
+[submodule "src/fosa"]
+       path = src/fosa
+       url = ../fosa
+[submodule "src/frsh"]
+       path = src/frsh
+       url = ../frsh
+[submodule "src/wvtest"]
+       path = src/wvtest
+       url = git://rtime.felk.cvut.cz/wvtest.git
diff --git a/README b/README
index 8b76ec525845ed3eb3e6f8395345196532c39455..68d2b820b4a23b4ecaf2ef93c05571f7c511a6f5 100644 (file)
--- a/README
+++ b/README
-FNA
-=====================
-Name:
-FNA
+* FRSH/FORB FRAMEWORK
 
-Version:
-May 2008
+  FRSH/FORB is a contract-based resource reservation framework for
+  distributed real-time applications. In general, it provides timing
+  isolation between applications, i.e. multiple applications can use
+  the same resources such as CPU, networks, etc., without influencing
+  timing of the other applications. The main principle is that
+  application developers use FRSH API to specify their resource
+  requirements needed to achieve desired timeliness and the framework
+  uses schedulability analysis to check these requirements. If the
+  check is successful an application is granted a "virtual resource"
+  which allow the application to use the requested resource while
+  enforcing the application not to use more than requested.
 
-Status:
-Alpha
+  The development of the framework begun in FRESCOR project
+  (http://frescor.org) and now it is developed as a stand-alone
+  project on SourceForge (http://frsh-forb.sf.net).
 
-Authors:
-Daniel Sangorrin [daniel.sangorrin@unican.es] (UC),
-Michael Gonzalez Harbour [mgh@unican.es] (UC)
-Martin Molnar (CTU)
-Michal Sojka (CTU)
+* BUILDING FRSH/FORB FRAMEWORK
 
-Licence:
-FRESCOR Lincece (see COPYING)
+1) Initialize and download additional submodules:
+   
+   git submodule init
+   git submodule update
 
-Brief description:
-This is FNA (Frescor Network Adaptation layer) module, the layer that allows
-to plug-in different network protocols to FRESCOR by means of a clear interface.
+2) Install prerequisites. On Debian/Ubuntu:
 
-URL:
-svn co http://www.frescor.org/private/svn/frescor/fna/trunk/
+     apt-get install libidl-dev libcpufreq-dev libacpi-dev \
+                    libcgroup-dev libncurses5-dev
 
-Bugs:
-See TODO
+   To build camera demo, you need to:
 
-Description:
+     apt-get install freeglut3-dev
 
-This is FNA (Frescor Network Adaptation layer) module, the layer that allows
-to plug-in different network protocols to FRESCOR by means of a clear interface.
+3) Go to build directory and configure the build:
+   
+   cd build/aquosa
+   make default-config
 
-- README: This file
+   If you are not satisfied with configuration found in
+   config.omk-default or config.target, you can override it in
+   config.omk.
 
-- COPYING: FRESCOR license
+   To be able to use CPU reservations AQuoSA
+   (http://aquosa.sourceforge.net) has to be installed. If you cannot
+   use AQuoSA, the framework can also be compiled without CPU support
+   (echo CONFIG_AQUOSA=n >> config.omk) or can use cgroups (echo
+   CONFIG_CPUCG=y >> config.omk). Note, that cgroups support is not
+   well tested, but we plan to work on it.
 
-- INSTALL: Installation instructions
+4) Compile it:
 
-- include/: FNA API C header files.
+   make
 
-- src/ : source code of FNA that is common to all protocols
+5) Test it:
 
-- src_xxx/ : source code of 'xxx' protocols
+   ./_compiled/bin/fcb &
+   ./_compiled/bin/frm_dummy &
+   ./_compiled/bin/frm_gui &
+   ./_compiled/bin-tests/dummy_renegotiation
 
-- doc/: documentation directory
+* DIRECTORY STRUCTURE
+
+  * build/* - configuration for different build targets
+
+  * build/aquosa - default build for linux
+
+  * build/marte - build for MarteOS. Not completely supported now.
+
+  * src - all sources
+
+  * src/forb - CORBA-like middle for interprocess and inter-node
+    communication.
+
+  * src/frsh - The core of resource reservation framework.
+
+  * src/frsh-include - FRSH API headers from FRESCOR project. Our FRSH
+    framework implements this API.
+
+  * src/fosa - Operating system adaptation layer
+
+  * src/ulut - library providing generic data types and algorithms
+    (AVL trees etc.).
+
+  * src/fna - Network adaptation layer = unified API for plugging in
+    different network protocols.
+
+  * src/fwp - Communication protocol and resource management for WiFi
+    (also works with Ethernet).
+
+* OLD HOWTO - may be out of date
+
+    Linux + AQuoSA
+
+     * Install AQuoSA (http://aquosa.sourceforge.net)
+     * $HOME/frescor/src/omk-build/aquosa
+     * Adjust symlinks to FRESCOR modules (fosa, frsh, utils, ...) or use ./create-links script
+     * Create config.omk containing (or use a shell variable in your .bashrc)
+
+  AQUOSA_ROOT=/path/to/aquosa/install/path
+
+     * Actually, my preferred way of working is adding the following
+       variables in .bashrc:
+
+  # AQuoSA environment
+  export AQUOSA_ROOT=/usr/local/aquosa
+  export PATH="$PATH:$AQUOSA_ROOT/bin"
+  export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$AQUOSA_ROOT/lib"
+  # FRESCOR environment
+  export PLATFORM=AQuoSA
+  export FOSA_ROOT=$HOME/path/to/fosa
+  export FRSH_ROOT=$HOME/path/to/frsh
+  export UTILS_ROOT=$HOME/path/to/utils
+  LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$FOSA_ROOT/lib:$FRSH_ROOT/lib:$UTILS_ROOT/lib"
+  # OMK environment
+  # Use `omk' for OMK-enabled sources
+  alias omk="make -f $HOME/path/to/Makefile.rules"
+  # link headers instead of copying them
+  export LN_HEADERS=y
+
+     * Create default-configuration by running
+
+  make default-config
+
+     * Run
+
+  make
+
+** Further remarks
+
+- If we are not interested in compilation of some component (because
+  it is currently in uncompilable state), we can simply delete the
+  link to it.
+
+- It might be possible that you will need to change some configuration
+  value from config.target. You can override any variable declared
+  there in config.omk. For example, if you have MARTE installed in a
+  different directory that the one specified in config.target, you can
+  put the following in config.omk:
+
+  MARTE_PATH=/path/to/marte/
+
+- To compile the FRESCOR for Marte, it is not necessary to set PATH
+  variable to GNAT compiler since OMK uses full paths to call the
+  compiler.
+
+- Since there are many things in uncompilable state, you may want to
+  use `make -k' to ignore compilation errors.
+
+- Since we don't want to modify the original Makefiles, in order to
+  compile only a part of the tree, you cannot simply run make in the
+  desired directory, but you have to specify -f flag with the path to
+  Makefile.rules. For this reason, we recommend defining the following
+  alias:
+
+  alias omk="make -f $HOME/frescor/src/omk-build/marte/Makefile.rules"
+
+** Why is OMK good for FRESCOR
+
+     * It is not easy to test FRESCOR simultaneously on multiple platforms.
+       With OMK, you can have the same sources compiled for multiple
+       platforms/targets at the same time because it uses out of source
+       directory compilation.
+     * Dependencies are not handled correctly in current Makefiles. For
+       example headers (in most tests) and some libraries (fosa_xxx) are not
+       specified as dependencies. OMK handles dependencies automatically, so
+       developers don't have to care about them.
+     * With OMK it is easy to combine multiple components/libraries (from
+       different developers) together and compile them with the same
+       configuration (e.g. PLATFORM variable). The structure of leaf
+       makefiles (Makefile for every component) is very simple and *well
+       specified*. Because of this it is easy to combine components from
+       multiple developers.
+     * Directory structure for compilation with current makefiles must be
+       fixed. In makefiles there is many "..". This prevents the use of
+       symbolic links to create desired directory structure because make
+       always treats ".." physically (i.e. it don't respect the directory
+       structure created by symbolic links). In OMK, the position of
+       directories in the source tree is not important. This is another
+       reason, why integration is simpler with OMK.
+     * OMK already supports compilation for user-space programs/libraries,
+       Linux and RTLinux modules, RTEMS and several other platforms. Now we
+       have also added support for Marte. It works under MinGW and Cygwin, so
+       it can be used to compile for OSE. In Pisa, they already use OMK for
+       Aquosa.
+
+** FAQ
+
+- How do I debug my Makefile.omk set-up ?
+
+   Just activate verbose compilation (V=1 or V=2):
+
+  make -f /path/to/Makefile.rules binary-pass V=1
+
+- How do I get back syntax highlighting in Emacs while editing .omk files ?
+
+   Just add these lines to your $(HOME)/.emacs:
+
+  (setq auto-mode-alist
+    (append '(("\.omk$"  . makefile-mode))
+      auto-mode-alist))
diff --git a/build/.gitignore b/build/.gitignore
new file mode 100644 (file)
index 0000000..3466337
--- /dev/null
@@ -0,0 +1,4 @@
+_compiled/
+_build/
+config.omk-default
+config.omk
diff --git a/build/aquosa/.gitignore b/build/aquosa/.gitignore
new file mode 100644 (file)
index 0000000..bcb062a
--- /dev/null
@@ -0,0 +1,2 @@
+cscope.files
+cscope.out
diff --git a/build/aquosa/Makefile b/build/aquosa/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/build/aquosa/Makefile.omk b/build/aquosa/Makefile.omk
new file mode 100644 (file)
index 0000000..7bc274f
--- /dev/null
@@ -0,0 +1,3 @@
+SUBDIRS=$(ALL_OMK_SUBDIRS) wvtest/c
+EXTRA_RULES_SUBDIRS = forb/forb-idl
+
diff --git a/build/aquosa/Makefile.rules b/build/aquosa/Makefile.rules
new file mode 100644 (file)
index 0000000..12aace8
--- /dev/null
@@ -0,0 +1,1424 @@
+#  Makefile.rules - OCERA make framework common project rules -*- makefile-gmake -*- #OMK:base.omk
+#
+#  (C) Copyright 2003, 2006, 2007, 2008, 2009  by Pavel Pisa - OCERA team member
+#  (C) Copyright 2006, 2007, 2008, 2009, 2010 by Michal Sojka - Czech Technical University, FEE, DCE
+#
+#  Homepage: http://rtime.felk.cvut.cz/omk/
+#  Version:  0.2-29-gac7ec3c
+#
+# The OMK build system is distributed under the GNU General Public
+# License.  See file COPYING for details.
+#
+#
+#                   Version for Linux/RTLinux builds.                            #OMK:linux.omk
+#
+#
+# input variables                                                                #OMK:base.omk
+# V                .. if set to 1, full command text is shown else short form is used
+# W                .. whole tree - if set to 1, make is always called from the top-level directory
+# SUBDIRS          .. list of subdirectories intended for make from actual directory
+# default_CONFIG   .. list of default config assignments CONFIG_XXX=y/n ...
+# wvtest_SCRIPTS    .. list of scripts producing wvtest output                   #OMK:wvtest.omk
+# wvtest_PROGRAMS   .. list of the testing programs producing wvtest output
+# LN_HEADERS       .. if "y", header files are symbolicaly linked instead of copied. #OMK:include.omk
+# input variables                                                                #OMK:linux.omk
+# lib_LIBRARIES    .. list of the user-space libraries
+# shared_LIBRARIES .. list of the user-space shared libraries
+# kernel_LIBRARIES .. list of the kernel-space libraries
+# rtlinux_LIBRARIES.. list of the RT-Linux kernel-space libraries
+# include_HEADERS  .. list of the user-space public header files
+# nobase_include_HEADERS .. public headers copied even with directory part
+# renamed_include_HEADERS .. public headers copied to the different target name
+# kernel_HEADERS   .. list of the kernel-space public header files
+# rtlinux_HEADERS  .. list of the RT-Linux kernel-space public header files
+# bin_PROGRAMS     .. list of the require binary programs
+# utils_PROGRAMS   .. list of the development utility programs
+# test_PROGRAMS    .. list of the testing programs
+# kernel_MODULES   .. list of the kernel side modules/applications
+# rtlinux_MODULES  .. list of RT-Linux the kernel side modules/applications
+# xxx_SOURCES      .. list of specific target sources
+# xxx_LIBS         .. list of specific target libraries (-l prefix is automatically added)
+# xxx_LDFLAGS      .. list of specific target LDFLAGS
+# lib_LOADLIBES    .. list of libraries linked to each executable
+# INCLUDES         .. additional include directories and defines for user-space
+# kernel_INCLUDES  .. additional include directories and defines for kernel-space
+# rtlinux_INCLUDES .. additional include directories and defines for RT-Linux
+# OMIT_KERNEL_PASSES  if defined, all kernel passes are omited
+#
+# LINUX_DIR        .. location of Linux kernel sources
+# RTL_DIR          .. location of RT-Linux sources
+# CFLAGS           .. C compiler flags
+# CXXFLAGS         .. C++ compiler flags
+# CPPFLAGS        .. C preprocessor flags
+# LDFLAGS         .. linker flags for programs linking
+# LOCAL_CONFIG_H   .. name of local config.h file generated from values          #OMK:config_h.omk
+#                     of options defined in the current directory
+# config_include_HEADERS .. names of global config files (possibly
+#                     with subdirectories)
+# xxx_DEFINES      .. list of config directives to be included in
+#                     config header file of the name <somedir>/xxx.h
+# DOXYGEN          .. if non-empty, generated headers includes Doxygen's @file
+#                    command, so it is possible to document config
+#                    variables.
+# QT_PROJECTS     .. list of QT .pro file to use for compilation                  #OMK:qt.omk
+# QT_SUBDIRS       .. subdirectories where to build QT applications using qmake (depricated)
+# QTDIR                   .. where QT resides
+OMK_RULES_TYPE=linux                                                             #OMK:Makefile.rules.linux@
+                                                                                 #OMK:base.omk@Makefile.rules.linux
+# If we are not called by OMK leaf Makefile...
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(abspath $(dir $(filter %Makefile.rules,$(MAKEFILE_LIST))))
+endif
+
+# OUTPUT_DIR is the place where _compiled, _build and possible other
+# files/directories are created. By default is the same as
+# $(MAKERULES_DIR).
+ifndef OUTPUT_DIR
+OUTPUT_DIR := $(MAKERULES_DIR)
+endif
+
+# We need to ensure definition of sources directory first
+ifndef SOURCES_DIR
+# Only shell built-in pwd understands -L
+SOURCES_DIR := $(shell ( pwd -L ) )
+INVOCATION_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+INVOCATION_DIR := $(INVOCATION_DIR:/%=%)
+INVOCATION_DIR := $(INVOCATION_DIR:\\%=%)
+endif
+
+.PHONY: all default check-make-ver print-hints omkize
+
+ifdef W
+  ifeq ("$(origin W)", "command line")
+    OMK_WHOLE_TREE:=$(W)
+  endif
+endif
+ifndef OMK_WHOLE_TREE
+  OMK_WHOLE_TREE:=0
+endif
+
+ifneq ($(OMK_WHOLE_TREE),1)
+all: check-make-ver print-hints default
+       @echo "Compilation finished"
+else
+# Run make in the top-level directory
+all:
+       @$(MAKE) -C $(MAKERULES_DIR) OMK_SERIALIZE_INCLUDED=n SOURCES_DIR=$(MAKERULES_DIR) RELATIVE_DIR="" $(MAKECMDGOALS) W=0
+endif
+
+ifdef OMK_TESTSROOT
+# Usage: $(call canttest,<error message>)
+define canttest
+       ( echo "$(1)" > $(OUTPUT_DIR)/_canttest; echo "$(1)"; exit 1 )
+endef
+else
+define canttest
+       echo "$(1)"
+endef
+endif
+
+#=========================
+# Include the config file
+
+ifndef CONFIG_FILE
+CONFIG_FILE      := $(OUTPUT_DIR)/config.omk
+endif
+
+$(CONFIG_FILE)-default:
+       $(MAKE) default-config 
+
+ifeq ($(MAKECMDGOALS),default-config)
+export DEFAULT_CONFIG_PASS=1
+endif
+
+ifneq ($(DEFAULT_CONFIG_PASS),1)
+include $(CONFIG_FILE)-default
+endif
+
+-include $(OUTPUT_DIR)/config.target
+
+ifneq ($(wildcard $(CONFIG_FILE)),)
+-include $(CONFIG_FILE)
+endif
+
+
+CONFIG_FILES ?= $(wildcard $(CONFIG_FILE)-default) $(wildcard $(OUTPUT_DIR)/config.target) $(wildcard $(CONFIG_FILE))
+
+
+export SOURCES_DIR MAKERULES_DIR RELATIVE_DIR INVOCATION_DIR
+export CONFIG_FILE CONFIG_FILES OMK_SERIALIZE_INCLUDED OMK_VERBOSE OMK_SILENT
+# OMK_SERIALIZE_INCLUDED has to be exported to submakes because passes
+# must to be serialized only in the toplevel make.
+
+ifndef RELATIVE_DIR
+RELATIVE_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+endif
+#$(warning  === RELATIVE_DIR = "$(RELATIVE_DIR)" ===)
+override RELATIVE_DIR := $(RELATIVE_DIR:/%=%)
+override RELATIVE_DIR := $(RELATIVE_DIR:\\%=%)
+#$(warning  RELATIVE_DIR = "$(RELATIVE_DIR)")
+#override BACK2TOP_DIR := $(shell echo $(RELATIVE_DIR)/ | sed -e 's_//_/_g' -e 's_/\./_/_g' -e 's_^\./__g'  -e 's_\([^/][^/]*\)_.._g' -e 's_/$$__')
+#$(warning  BACK2TOP_DIR = "$(BACK2TOP_DIR)")
+
+#$(warning SOURCES_DIR = "$(SOURCES_DIR)")
+#$(warning MAKERULES_DIR = "$(OUTPUT_DIR)")
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+
+# We have to use RELATIVE_PREFIX because of mingw
+override RELATIVE_PREFIX := $(RELATIVE_DIR)/
+override RELATIVE_PREFIX := $(RELATIVE_PREFIX:/%=%)
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+# Define srcdir for Automake compatibility
+srcdir = $(SOURCES_DIR)
+
+# Defines for quiet compilation
+ifdef V
+  ifeq ("$(origin V)", "command line")
+    OMK_VERBOSE = $(V)
+  endif
+endif
+ifndef OMK_VERBOSE
+  OMK_VERBOSE = 0
+endif
+ifneq ($(OMK_VERBOSE),0)
+  Q =
+else
+  Q = @
+endif
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+  QUIET_CMD_ECHO = true
+  OMK_SILENT = 1
+else
+  QUIET_CMD_ECHO = echo
+endif
+
+MAKEFILE_OMK=Makefile.omk
+# All subdirectories (even linked ones) containing Makefile.omk
+# Usage in Makefile.omk: SUBDIRS = $(ALL_OMK_SUBDIRS)
+ALL_OMK_SUBDIRS = $(patsubst %/$(MAKEFILE_OMK),%,$(patsubst $(SOURCES_DIR)/%,%,$(wildcard $(SOURCES_DIR)/*/$(MAKEFILE_OMK))))
+
+# ===================================================================
+# We have set up all important variables, so we can check and include
+# real OCERA style Makefile.omk now
+ifndef OMK_INCLUDED
+include $(SOURCES_DIR)/$(MAKEFILE_OMK)
+ifeq ($(AUTOMATIC_SUBDIRS),y)
+SUBDIRS?=$(ALL_OMK_SUBDIRS)
+endif
+OMK_INCLUDED := 1
+endif
+
+print-hints:
+       @echo 'Use "make V=1" to see the verbose compile lines.'
+
+check-make-ver:
+       @GOOD_MAKE_VERSION=`echo $(MAKE_VERSION) | sed -n -e 's/^[4-9]\..*\|^3\.9[0-9].*\|^3\.8[1-9].*/y/p'` ; \
+       if [ x$$GOOD_MAKE_VERSION != xy ] ; then \
+               echo "Your make program version is too old and does not support OMK system." ; \
+               echo "Please update to make program 3.81beta1 or newer." ; exit 1 ; \
+       fi
+
+distclean dist-clean:
+       @$(QUIET_CMD_ECHO) "  RM      $(COMPILED_DIR_NAME) $(BUILD_DIR_NAME)"
+       @rm -fr $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)  $(OUTPUT_DIR)/$(BUILD_DIR_NAME)
+
+# Common OMK templates
+# ====================
+
+# Syntax: $(call mkdir,<dir name>)
+define mkdir_def
+       [ -d $(1) ] || mkdir -p $(1) || exit 1
+endef
+
+ifneq ($(OMK_VERBOSE),2)
+NO_PRINT_DIRECTORY := --no-print-directory
+endif
+
+ifeq ($(USE_LEAF_MAKEFILES),n)
+export USE_LEAF_MAKEFILES
+SUBDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+SOURCESDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+else
+SUBDIR_MAKEFILE=$(SOURCES_DIR)/$(3)/Makefile
+SOURCESDIR_MAKEFILE=$(SOURCES_DIR)/Makefile
+endif
+
+pass = $(strip $(1))
+
+unexport SUBDIRS
+
+# Call a pass in a subdirectory
+# Usage: $(call omk_pass_subdir_template,<pass name>,<build dir>,<subdir>)
+define omk_pass_subdir_template
+.PHONY: $(pass)-$(3)-subdir
+$(pass)-submakes: $(pass)-$(3)-subdir
+$(pass)-$(3)-subdir: MAKEOVERRIDES:=$(filter-out SUBDIRS=%,$(MAKEOVERRIDES))
+$(pass)-$(3)-subdir:
+       @$(call mkdir_def,$(2)/$(3))
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(3) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(3) -C $(2)/$(3) \
+               -f $(SUBDIR_MAKEFILE) $(pass)-submakes
+# In subdirectories we can call submakes directly since passes are
+# already serialized on the toplevel make.
+endef
+
+ifdef OMK_TESTSROOT
+check-target = $(1:%=%-check)
+endif
+
+# Call a pass in a subdirectory
+# Usage: $(call extra_rules_subdir_template,<subdir>)
+define extra_rules_subdir_template
+extra-rules-subdirs: extra-rules-$(1)
+extra-rules-$(1):
+       +@$(MAKE) OMK_SERIALIZE_INCLUDED=n MAKERULES_DIR=$(SOURCES_DIR)/$(1) OUTPUT_DIR=$(OUTPUT_DIR) \
+               SOURCES_DIR=$(SOURCES_DIR)/$(1) RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) -C $(SOURCES_DIR)/$(1)
+endef
+
+.PHONY: extra-rules-subdirs
+extra-rules-subdirs:
+
+$(foreach subdir,$(EXTRA_RULES_SUBDIRS),$(eval $(call extra_rules_subdir_template,$(subdir))))
+
+# Usage: $(call omk_pass_template,<pass name>,<build dir>,[<local make flags>],[<local enable condition>])
+define omk_pass_template
+.PHONY: $(pass) $(pass)-local $(pass)-check $(pass)-submakes
+$(foreach subdir,$(SUBDIRS),$(eval $(call omk_pass_subdir_template,$(pass),$(2),$(subdir))))
+$(pass):
+# Submakes have to be called this way and not as dependecies for pass
+# serialization to work
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_DIR) \
+               -f $(SOURCESDIR_MAKEFILE) $(pass)-submakes
+$(pass)-submakes:
+       @true                   # Do not emit "nothing to be done" messages
+
+ifneq ($(4)$($(pass)_HOOKS),)
+$(pass)-submakes: $(pass)-this-dir
+$(pass)-this-dir: $(foreach subdir,$(SUBDIRS),$(pass)-$(subdir)-subdir)
+       +@echo "make[omk]: $(pass) in $(RELATIVE_DIR)"
+       @$(call mkdir_def,$(2))
+       +@$(MAKE) $(NO_PRINT_DIRECTORY) SOURCES_DIR=$(SOURCES_DIR) RELATIVE_DIR=$(RELATIVE_DIR) -C $(2) \
+               -f $(SOURCESDIR_MAKEFILE) $(3) $(check-target) $(1:%=%-local)
+$(pass)-local: $($(pass)_HOOKS)
+endif
+endef
+
+# =======================
+# DEFAULT CONFIG PASS
+
+default-config:
+       @echo "# Start of OMK config file" > "$(CONFIG_FILE)-default"
+       @echo "# This file should not be altered manually" >> "$(CONFIG_FILE)-default"
+       @echo "# Overrides should be stored in file $(notdir $(CONFIG_FILE))" >> "$(CONFIG_FILE)-default"
+       @echo >> "$(CONFIG_FILE)-default"
+       @$(MAKE) $(NO_PRINT_DIRECTORY) -C $(OUTPUT_DIR) \
+               RELATIVE_DIR="" SOURCES_DIR=$(OUTPUT_DIR) \
+               -f $(OUTPUT_DIR)/Makefile default-config-pass
+
+$(eval $(call omk_pass_template,default-config-pass,$$(LOCAL_BUILD_DIR),,always))
+
+default-config-pass-local:
+#      @echo Default config for $(RELATIVE_DIR)
+       @echo "# Config for $(RELATIVE_DIR)" >> "$(CONFIG_FILE)-default"
+       @$(foreach x, $(default_CONFIG), echo '$(x)' | \
+               sed -e 's/^[^=]*=x$$/#\0/' >> "$(CONFIG_FILE)-default" ; )
+
+
+omkize:
+       $(Q)if ! grep -q MAKERULES_DIR Makefile; then \
+          echo "Makefile is not OMK leaf makefile!" >&2; exit 1; \
+       fi
+       $(Q)for i in `find -L . -name Makefile.omk` ; do \
+          d=`dirname $${i}`; \
+          if ! test -f "$${d}/Makefile.rules" && ( test -f "$${d}/Makefile" && ! cmp --silent Makefile "$${d}/Makefile" ); then \
+             rm -f "$${d}/Makefile"; \
+             cp -v Makefile "$${d}/Makefile"; \
+          fi \
+       done
+                                                                                 #OMK:wvtest.omk@Makefile.rules.linux
+# Documentation: wvtest_PROGRAMS is equivalent to test_PROGRAMS. The
+# difference is that it is automatically run during "make wvtest".
+test_PROGRAMS += $(wvtest_PROGRAMS)
+
+# Documentation: If your project uses wvtest, it is recomended to put
+# the "test: wvtest" rule to config.target.
+wvtest:
+       $(Q)$(MAKERULES_DIR)/wvtestrun $(MAKE) wvtest-pass
+
+.PHONY: wvtest
+
+$(eval $(call omk_pass_template,wvtest-pass,$$(LOCAL_BUILD_DIR),,$(wvtest_SCRIPTS)$(wvtest_PROGRAMS)))
+
+# Usage: $(call wvtest_template,<shell command>)
+define wvtest_template
+wvtest-pass-local: wvtest-run-$(1)
+.PHONY: wvtest-run-$(1)
+wvtest-run-$(1):
+       mkdir -p $(1).wvtest
+       cd $(1).wvtest && $(1)
+endef
+
+# Documentation: Write the test so, that it can be run from arbitrary
+# directory, i.e. in case of a script ensure that the wvtest library
+# is sourced like this:
+#
+# . $(dirname $0)/wvtest.sh
+
+$(foreach script,$(wvtest_SCRIPTS),$(eval $(call wvtest_template,$(SOURCES_DIR)/$(script))))
+# Hack!!!
+USER_TESTS_DIR := $(OUTPUT_DIR)/_compiled/bin-tests
+$(foreach prog,$(wvtest_PROGRAMS),$(eval $(call wvtest_template,$(USER_TESTS_DIR)/$(prog))))
+ifeq ($(OMK_VERBOSE),1)                                                          #OMK:include.omk@Makefile.rules.linux
+CPHEADER_FLAGS += -v
+LNHEADER_FLAGS += -v
+endif
+
+ifneq ($(LN_HEADERS),y)
+define cp_cmd
+if ! cmp --quiet $(1) $(2); then \
+    echo "  CP      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; \
+    install -C -D $(CPHEADER_FLAGS) $(1) $(2) || exit 1; \
+fi
+endef
+else
+define cp_cmd
+if ! cmp --quiet $(1) $(2); then \
+    echo "  LN      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; \
+    if [ -f $(1) ]; then d=$(2); mkdir -p $${d%/*} && ln -sf $(LNHEADER_FLAGS) $(1) $(2) || exit 1; else exit 1; fi; \
+fi
+endef
+endif
+
+# TODO: Check modification date of changed header files. If it is
+# newer that in source dir, show a warning.
+
+# Syntax: $(call include-pass-template,<include dir>,<keyword>)
+define include-pass-template
+include-pass-local: include-pass-local-$(2)
+include-pass-local-$(2): $$($(2)_GEN_HEADERS) $$(foreach f,$$(renamed_$(2)_GEN_HEADERS),$$(shell f='$$(f)'; echo $$$${f%->*}))
+       @$$(foreach f, $$($(2)_HEADERS),$$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(notdir $$(f))); )
+# FIXME: Use correct build dir, then document it (in the line bellow)
+       @$$(foreach f, $$($(2)_GEN_HEADERS),$$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$(f),$(1)/$$(notdir $$(f))); )
+       @$$(foreach f, $$(nobase_$(2)_HEADERS), $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(f)); )
+       @$$(foreach f, $$(renamed_$(2)_HEADERS), \
+          f='$$(f)'; srcfname=$$$${f%->*}; destfname=$$$${f#*->}; \
+          $$(call cp_cmd,$$(SOURCES_DIR)/$$$${srcfname},$(1)/$$$${destfname}); )
+       @$$(foreach f, $$(renamed_$(2)_GEN_HEADERS), \
+          f='$$(f)'; srcfname=$$$${f%->*}; destfname=$$$${f#*->}; \
+          $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$$${srcfname},$(1)/$$$${destfname}); )
+# Suppress "Nothing to be done for `include-pass-local'" message if no headers are defined in Makefile.omk
+       @$$(if $$($(2)_HEADERS)$$($(2)_GEN_HEADERS)$$(nobase_$(2)_HEADERS)$$(renamed_$(2)_HEADERS)$$(renamed_$(2)_GEN_HEADERS),,true)
+endef
+                                                                                 #OMK:linux.omk@Makefile.rules.linux
+# Hack to check RT-Linux rules
+#LINUX_DIR := /home/cvs/ocera/ocera-build/kernel/linux
+#RTL_DIR := /home/cvs/ocera/ocera-build/kernel/rtlinux
+#CONFIG_RTLINUX = y
+#OCERA_DIR := $(shell ( cd -L $(OUTPUT_DIR)/../../.. ; pwd -L ) )
+
+-include $(OUTPUT_DIR)/OCERA_TOP_DIR
+
+BUILD_DIR_NAME = _build
+COMPILED_DIR_NAME = _compiled
+ifndef GROUP_DIR_NAME
+GROUP_DIR_NAME = nogroup
+endif
+
+ifdef OCERA_DIR
+ifeq ($(wildcard $(OCERA_DIR)/ocera.mk),)
+$(warning "ocera.mk" file does not exist. Adapt Makefile.rules for standalone compilation)
+$(warning (comment out definition of OCERA_DIR line and optionally select RTL_DIR) )
+$(error or go to the ocera/ directory and do 'make' to generate the "ocera.mk" file first, please)
+endif
+include $(OCERA_DIR)/ocera.mk
+KERN_INCLUDE_DIR := $(OCERA_KERNEL_INCLUDES_DIR)
+KERN_LIB_DIR     := $(OCERA_KERNEL_LIBRARIES_DIR)
+KERN_MODULES_DIR := $(OCERA_MODULES_DIR)
+KERN_BUILD_DIR   := $(BUILD_DIR)/kern/$(GROUP_DIR_NAME)
+KERN_MODPOST_DIR := $(BUILD_DIR)/kern-modpost
+USER_INCLUDE_DIR := $(OCERA_USER_INCLUDES_DIR)
+USER_LIB_DIR     := $(OCERA_USER_LIBRARIES_DIR)
+USER_UTILS_DIR   := $(TARGET_DIR)/usr/bin
+USER_TESTS_DIR   := $(TARGET_DIR)/usr/bin
+USER_BIN_DIR     := $(TARGET_DIR)/usr/bin
+USER_BUILD_DIR   := $(BUILD_DIR)/user/$(GROUP_DIR_NAME)
+#LINUX_DIR        := $(OCERA_DIR)/kernel/linux
+#RTL_DIR          := $(OCERA_DIR)/kernel/rtlinux
+#CONFIG_FILE      := $(OCERA_DIR)/emdebsys/.config 
+ifneq ($(wildcard $(CONFIG_FILE)),)
+CONFIG_FILE_OK = y
+endif
+else # OCERA_DIR
+KERN_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include-kern
+KERN_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib-kern
+KERN_MODULES_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/modules
+KERN_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern
+KERN_MODPOST_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern-modpost
+USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include
+USER_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib
+USER_UTILS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils
+USER_TESTS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests
+USER_BIN_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin
+USER_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user
+
+ifndef LINUX_VERSION
+LINUX_VERSION=$(shell uname -r)
+endif
+ifndef LINUX_DIR
+LINUX_DIR=/lib/modules/$(LINUX_VERSION)/build
+endif
+endif # OCERA_DIR
+
+ifeq ($(BUILD_OS),)
+  # Check for target
+  ifeq ($(OS),Windows_NT)
+    BUILD_OS := win32
+  else
+    BUILD_OS := $(shell uname | tr '[A-Z]' '[a-z]' )
+    #$(warning BUILD_OS=$(BUILD_OS))
+  endif
+endif
+
+ifeq ($(TARGET_OS),)
+  TARGET_OS := $(BUILD_OS)
+endif
+
+export TARGET_OS
+export BUILD_OS
+
+LOCAL_BUILD_DIR  = $(USER_OBJS_DIR)
+
+# Assign default values to CFLAGS variable. If the variable is defined
+# earlier (i.g. in config.omk), it is not overriden here.
+CFLAGS ?= -O2 -Wall
+CXXFLAGS ?= -O2 -Wall
+
+
+CPPFLAGS  += -I $(USER_INCLUDE_DIR)
+
+LOADLIBES += -L$(USER_LIB_DIR) 
+
+LOADLIBES += $(lib_LOADLIBES:%=-l%)
+
+LIB_CPPFLAGS += $(CPPFLAGS)
+LIB_CFLAGS   += $(CFLAGS)
+
+ifeq ($(TARGET_OS),win32)
+  EXE_SUFFIX = .exe
+  SOLIB_EXT = dll
+else
+  SOLIB_EXT = so
+  SOLIB_PICFLAGS += -fpic
+endif
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR)
+KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR)
+OMK_WORK_DIR  = $(USER_OBJS_DIR)
+
+.PHONY: dep subdirs clean clean-custom cleandepend check-dir
+
+# Some support to serialize some targets for parallel make
+ifneq ($(OMK_SERIALIZE_INCLUDED),y)
+include-pass: check-dir
+library-pass: include-pass
+link-pseudo-pass: library-pass
+binary-pass: link-pseudo-pass
+kernel-lib-pass: include-pass
+kernel-mod-pass: kernel-lib-pass
+kernel-modpost-pass: kernel-mod-pass
+kernel-pass: kernel-mod-pass kernel-modpost-pass
+
+override OMK_SERIALIZE_INCLUDED = y
+MAKEOVERRIDES := $(filter-out OMK_SERIALIZE_INCLUDED=n,$(MAKEOVERRIDES))
+endif
+
+# Checks for OMK tester
+ifdef OMK_TESTSROOT
+default-config-pass-check include-pass-check:
+library-pass-check binary-pass-check:
+       @[ -x "$(shell which $(CC))" ] || $(call canttest,Cannot find compiler: $(CC))
+endif
+
+#=====================================================================
+# User-space rules and templates to compile programs, libraries etc.
+
+ifdef USER_RULE_TEMPLATES
+
+USER_SOURCES2OBJS = .o/.c .o/.cc .o/.cxx .o/.S .o/.o
+
+USER_SOURCES2OBJSLO = .lo/.c .lo/.cc .lo/.cxx .lo/.S .lo/.lo
+
+#%.lo: %.c
+#      $(CC) -o $@ $(LCFLAGS) -c $<
+
+c_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+cc_o_COMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+S_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASFLAGS) -DOMK_FOR_USER
+
+idl_COMPILE = $(IDL_COMPILER)
+
+# Check GCC version for user build
+ifndef CC_MAJOR_VERSION
+CC_MAJOR_VERSION := $(shell $(CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(CC_MAJOR_VERSION),2)
+CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+
+# Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_c_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CC      $$@"
+       $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_cc_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CXX     $$@"
+       $(Q) if $$(cc_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_S_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  AS      $$@"
+       $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+NM ?= nm
+
+# Syntax: $(call CMETRIC_o_h_template,<object_file>,<target_header>)
+define CMETRIC_o_h_template
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CMETRIC $$@"
+       $(Q)if [ -n `dirname $$@` ] ; then \
+             if [ ! -e `dirname $$@` ] ; then \
+               mkdir -p `dirname $$@` ; fi ; fi
+       $(Q)echo >$$@.tmp '/* Automatically generated from $$< */'
+       $(Q)echo >>$$@.tmp '/* Conditionals to control compilation */'
+# Bellow, the tricks with redirection are for shells without set -o pipefail
+# (see http://www.mail-archive.com/dash@vger.kernel.org/msg00149.html)
+       $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) $$<; echo $$$$? >&4; }\
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2cond_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@.tmp` && exit $$$$status
+       $(Q)echo >>$$@.tmp '/* Defines from the values defined to symbols in hexadecimal format */'
+       $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) $$<; echo $$$$? >&4; }\
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2def_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@.tmp` && exit $$$$status
+       $(Q)echo >>$$@.tmp '/* Defines from the values defined to symbols in decimal format */'
+       $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) -td $$<; echo $$$$? >&4; }\
+               | sed -n 's/^ *0*\(0\|[1-9][0-9]*\) *A *_cmetric2defdec_\([A-Za-z_0-9]*\) */#define \2 \1/p' \
+               | sort >>$$@.tmp` && exit $$$$status
+       $(Q)mv $$@.tmp $$@
+endef
+
+
+
+define COMPILE_idl_template
+$(2).c $(2)-stubs.c $(2)-skels.c $(2)-common.c $(2).h: $(1) $$(wildcard $$(firstword $$(idl_COMPILE)))
+       @$(QUIET_CMD_ECHO) "  IDL     $$@"
+       $(Q) $$(idl_COMPILE) $$($(2)_IDLFLAGS) $(1)
+endef
+
+
+# Syntax: $(call PROGRAM_template,<dir>,<executable-name>,<executable-suffix>,<linker-sript>)
+# FIXME: ???????? asi je tu blbej komentar
+define PROGRAM_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(2)/$(1)$(3): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q) $$(if $$(filter %.cc,$$($(1)_SOURCES:%.cxx=%.cc)),$$(CXX),$$(CC)) \
+         $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(LDFLAGS) $$($(1)_LDFLAGS) -Wl,-rpath-link,$(USER_LIB_DIR) -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$@
+       @echo "$(2)/$(1)$(3): \\" >$(USER_OBJS_DIR)/$(1).exe.d
+       @sed -n -e 's|^LOAD \(.*\)$$$$|  \1  \&|p' $(USER_OBJS_DIR)/$(1).exe.map|tr '&' '\134'  >>$(USER_OBJS_DIR)/$(1).exe.d
+       @echo >>$(USER_OBJS_DIR)/$(1).exe.d
+endef
+
+
+# Syntax: $(call LIBRARY_template,<library-name>)
+define LIBRARY_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR      $$@"
+       $(Q) $(AR) rcs $$@ $$^
+endef
+
+.PHONY: FORCE
+
+# Syntax: $(call SOLIB_template,<library-name>)
+define SOLIB_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+SOLIB_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJSLO),
+$(1)_OBJSLO += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJSLO := $$(sort $$($(1)_OBJSLO:%/=%))
+
+SOLIB_OBJS  += $$($(1)_OBJSLO)
+SOLIB_SOURCES += $$($(1)_SOURCES)
+
+$(OMK_WORK_DIR)/lib$(1).$(SOLIB_EXT).omkvar: $$($(1)_OBJSLO) FORCE
+       $(Q)echo '$(1)_objslo += $$$$(addprefix $(USER_OBJS_DIR)/,$$($(1)_OBJSLO))' > $$@.tmp; \
+           echo '$(1)_libs += $$($(1)_LIBS) $$(lib_LOADLIBES)' >> $$@.tmp; \
+           echo '$(1)_ldflags += $$($(1)_LDFLAGS) $$(lib_LDFLAGS)' >> $$@.tmp; \
+           echo 'shared_libs := $$$$(sort $(1) $$$$(shared_libs))' >> $$@.tmp; \
+           if cmp -s $$@.tmp $$@; then rm $$@.tmp; else mv $$@.tmp $$@; fi
+endef
+
+library-pass-local: $(addprefix $(USER_INCLUDE_DIR)/,$(cmetric_include_HEADERS)) \
+                   $(lib_LIBRARIES:%=$(USER_LIB_DIR)/lib%.a) $(shared_LIBRARIES:%=$(OMK_WORK_DIR)/lib%.$(SOLIB_EXT).omkvar)
+
+binary-pass-local: $(bin_PROGRAMS:%=$(USER_BIN_DIR)/%$(EXE_SUFFIX)) $(utils_PROGRAMS:%=$(USER_UTILS_DIR)/%$(EXE_SUFFIX)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%$(EXE_SUFFIX))
+
+# Special rules for CMETRIC generated headers
+
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call COMPILE_c_o_template,\
+               $(SOURCES_DIR)/$($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES),\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),)))
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call CMETRIC_o_h_template,\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),\
+               $(addprefix $(USER_INCLUDE_DIR)/,$(cmetrh)))))
+
+GEN_HEADERS+=$(cmetric_include_HEADERS:%=$(USER_INCLUDE_DIR)/%)
+
+GEN_HEADERS+=$(filter %.h,$(USER_IDLS:%.idl=%.h))
+
+# Generate rules for compilation of programs and libraries
+
+$(foreach prog,$(utils_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_UTILS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(test_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(bin_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR),$(EXE_SUFFIX))))
+
+$(foreach lib,$(lib_LIBRARIES),$(eval $(call LIBRARY_template,$(lib))))
+
+$(foreach lib,$(shared_LIBRARIES),$(eval $(call SOLIB_template,$(lib))))
+
+-include $(USER_OBJS_DIR)/*.d
+#FIXME: This doesn't include dependencies of source files from
+#subdirectories (i.s. *_SOURCES=dir/file.c. I'm currently not sure,
+#how to handle this.
+
+endif # USER_RULE_TEMPLATES
+
+.PHONY: link-pseudo-pass
+link-pseudo-pass:
+       $(Q)$(MAKE) $(NO_PRINT_DIRECTORY) -C $(USER_BUILD_DIR) -f $(SOURCESDIR_MAKEFILE) link-shared-libs
+
+ifeq ($(MAKECMDGOALS),link-shared-libs)
+
+# Syntax: $(call solib_link_template,<library-name>)
+define solib_link_template
+$(1)_shared_libs = $$(patsubst %,$(USER_LIB_DIR)/lib%.$(SOLIB_EXT),$$(filter $$(shared_libs),$$($(1)_libs)))
+#$$(warning $(1)_shared_libs = $$($(1)_shared_libs))
+$(USER_LIB_DIR)/lib$(1).$(SOLIB_EXT): $$($(1)_shared_libs) $$($(1)_objslo)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q)$(CC) --shared -Xlinker -soname=lib$(1).$(SOLIB_EXT) -Wl,-Map,$(USER_OBJS_DIR)/lib$(1).$(SOLIB_EXT).map -o $$@ $$($(1)_objslo) $$(LOADLIBES) $$($(1)_libs:%=-l%) $$(lib_ldflags) $$($(1)_ldflags)
+endef
+
+-include $(shell true; find $(USER_BUILD_DIR) -name 'lib*.omkvar') # `true' is a hack for MinGW
+#$(warning $(shared_libs))
+$(foreach lib,$(shared_libs),$(eval $(call solib_link_template,$(lib))))
+
+.PHONY: link-shared-libs
+link-shared-libs: $(shared_libs:%=$(USER_LIB_DIR)/lib%.$(SOLIB_EXT))
+endif # link-shared-libs
+
+#=====================================================================
+# Kernel-space rules and templates to compile modules, libraries etc.
+
+ifdef KERN_RULE_TEMPLATES
+
+$(KERN_LIB_DIR)/kernel.mk: $(LINUX_DIR)/.config $(MAKERULES_DIR)/kernelcfg2mk
+       @$(QUIET_CMD_ECHO) "  KCFG2MK $@"
+       $(Q) $(MAKERULES_DIR)/kernelcfg2mk $(LINUX_DIR) $(KERN_LIB_DIR)
+
+ifeq ($(CONFIG_RTLINUX),y)
+include $(RTL_DIR)/rtl.mk
+
+KERN_CC = $(CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+INCLUDES := -I $(KERN_INCLUDE_DIR) $(INCLUDE) $(rtlinux_INCLUDES) $(kernel_INCLUDES)
+#-DEXPORT_NO_SYMBOLS
+c_o_kern_COMPILE = $(KERN_CC) -idirafter $(kern_GCCLIB_DIR)/include $(INCLUDES)  $(CFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(CXX) $(INCLUDES) $(CXXFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := .o
+KERN_ARCH = $(ARCH)
+KERN_LD = $(LD)
+KERN_AR = $(AR)
+
+else # CONFIG_RTLINUX
+
+include $(KERN_LIB_DIR)/kernel.mk
+
+ifeq ($(LINUX_SRC),)
+LINUX_SRC = $(LINUX_DIR)
+endif
+kernel_INCLUDES += -I $(KERN_INCLUDE_DIR) -I $(LINUX_DIR) -idirafter $(LINUX_SRC)/include/linux
+
+ifdef LINUX_CC
+KERN_CC = $(LINUX_CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(LINUX_CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+else
+KERN_CC = echo KERN_CC not defined - compilation skipped
+endif
+c_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+S_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_AFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+KERN_EXE_SUFFIX := $(LINUX_MODULE_EXT)
+KERN_LDFLAGS = $(LINUX_LDFLAGS)
+ifdef LINUX_ARCH
+KERN_ARCH = $(LINUX_ARCH)
+else
+KERN_ARCH = echo KERN_ARCH not defined - skipped
+endif
+ifdef LINUX_LD
+KERN_LD = $(LINUX_LD)
+else
+KERN_LD = echo KERN_LD  not defined - skipped
+endif
+ifneq ($(LINUX_AR),)
+KERN_AR = $(LINUX_AR)
+else
+KERN_AR = $(AR)
+endif
+ifeq ($(LINUX_QUOTE_MODNAME),y)
+KERN_MQ=\"
+KERN_KBUILD_MODNAME=-D"KBUILD_MODNAME=((THIS_MODULE)!=NULL?(THIS_MODULE)->name:NULL)"
+endif
+endif # CONFIG_RTLINUX
+
+KERN_LOADLIBES += -L$(KERN_LIB_DIR) 
+
+KERN_LOADLIBES += $(rtlinux_LOADLIBES:%=-l%)
+KERN_LOADLIBES += $(kernel_LOADLIBES:%=-l%)
+
+
+
+# Check GCC version for kernel part of build
+ifndef kern_CC_MAJOR_VERSION
+kern_CC_MAJOR_VERSION := $(shell $(KERN_CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(kern_CC_MAJOR_VERSION),2)
+kern_CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+kern_CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+ifeq ($(KERN_EXE_SUFFIX),.ko)
+ifeq ($(wildcard $(LINUX_DIR)/scripts/mod/modpost),)
+KERN_MODPOST = $(LINUX_DIR)/scripts/modpost
+else
+KERN_MODPOST = $(LINUX_DIR)/scripts/mod/modpost
+endif
+KERN_MODULES_LINK_DIR = $(KERN_MODPOST_DIR)
+KERN_LINK_SUFFIX = .o
+else
+KERN_MODULES_LINK_DIR = $(KERN_MODULES_DIR)
+KERN_LINK_SUFFIX = $(KERN_EXE_SUFFIX)
+endif
+
+ifeq ($(LINUX_CONFIG_MODVERSIONS),y)
+MODPOST_OPTS += -m
+MODPOST_OPTS += -i $(LINUX_DIR)/Module.symvers
+ifneq ($(LINUX_BUILDHOST),) # this is not correct point, it should look for 2.6.17 kernel
+MODPOST_OPTS += -I $(KERN_LIB_DIR)/Module.symvers
+endif
+MODPOST_OPTS += -o $(KERN_LIB_DIR)/Module.symvers
+endif
+
+ifeq ($(LINUX_CONFIG_DEBUG_SECTION_MISMATCH),y)
+MODPOST_OPTS += -S
+endif
+
+ifeq ($(LINUX_CONFIG_MARKERS),y)
+MODPOST_OPTS += -K $(LINUX_DIR)/Module.markers
+MODPOST_OPTS += -M $(KERN_LIB_DIR)/Module.markers
+endif
+
+ifeq ($(LINUX_KBUILD_MODPOST_WARN),y)
+MODPOST_OPTS += -w
+endif
+
+ifneq ($(LINUX_BUILDHOST),)
+ifneq ($(LINUX_BUILDHOST),$(LINUX_ARCH))
+MODPOST_OPTS += -c
+endif
+endif
+
+define COMPILE_c_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CC [K]  $$@"
+       $(Q) if $$(c_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_cc_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CXX [K] $$@"
+       $(Q) if $$(cc_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_S_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  AS [K]  $$@"
+       $(Q) if $$(S_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define MODULE_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+# this is hack to build "__this_module" structure for 2.6.x kernels
+# modpost is used for that purpose now
+
+#$(1).mod.c:
+#      echo  "\
+#      #include <linux/version.h>@\
+#      #include <linux/module.h>@\
+#      #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5))@\
+#      #include <linux/vermagic.h>@\
+#      #include <linux/compiler.h>@\
+#      @\
+#      MODULE_INFO(vermagic, VERMAGIC_STRING);@\
+#      @\
+#      #undef unix@\
+#      struct module __this_module@\
+#      __attribute__((section(\".gnu.linkonce.this_module\"))) = {@\
+#       .name = __stringify(KBUILD_MODNAME),@\
+#       .init = init_module,@\
+#      #ifdef CONFIG_MODULE_UNLOAD@\
+#       .exit = cleanup_module,@\
+#      #endif@\
+#      };@\
+#      #endif@\
+#      " | tr @ \\n >$$@ 
+
+
+#$(eval $(call COMPILE_c_o_kern_template,$(1).mod.c,$(1).mod.o,-DKBUILD_MODNAME=$(1)))
+
+$(2)/$(1)$(KERN_LINK_SUFFIX): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LD [K]  $$@"
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) -r $$($(1)_OBJS) -L$$(kern_GCCLIB_DIR) $$($(1)_LIBS:%=-l%) $$(KERN_LOADLIBES) -Map $(KERN_OBJS_DIR)/$(1).mod.map -o $$@
+       @echo "$(2)/$(1)$(KERN_LINK_SUFFIX): \\" >$(KERN_OBJS_DIR)/$(1).mod.d
+       @sed -n -e 's/^LOAD \(.*\)$$$$/  \1  \\/p' $(KERN_OBJS_DIR)/$(1).mod.map  >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @echo >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @if [ "$(KERN_EXE_SUFFIX)" = ".ko" ] ; then \
+         echo $(1) >>$(KERN_MODPOST_DIR)/module-changes ; \
+         echo $(1) >$(KERN_MODPOST_DIR)/$(1).mod.stamp ; \
+       fi
+
+endef
+
+
+
+define LIBRARY_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+$(KERN_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR [K]  $$@"
+       $(Q) $(KERN_AR) rcs $$@ $$^
+endef
+
+
+ifdef LINUX_DIR
+
+kernel-lib-pass-local: $(kernel_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+kernel-mod-pass-local: $(kernel_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+$(foreach module,$(kernel_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(kernel_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+
+ifeq ($(CONFIG_RTLINUX),y)
+
+kernel-mod-pass-local: $(rtlinux_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+kernel-lib-pass-local: $(rtlinux_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+$(foreach module,$(rtlinux_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(rtlinux_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+ifeq ($(KERN_MODPOST_PASS),y)
+
+MODULES_LIST :=        $(wildcard *.mod.stamp)
+MODULES_LIST := $(MODULES_LIST:%.mod.stamp=%)
+
+define MODPOST_kern_template
+$(2) : $(1)$(KERN_LINK_SUFFIX) $(1).mod.c
+       @$(QUIET_CMD_ECHO) "  LD [M]  $$@"
+       $(Q) $$(c_o_kern_COMPILE) -D"KBUILD_BASENAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -D"KBUILD_MODNAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -o $(1).mod.o -c $(1).mod.c
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) $(1)$(KERN_LINK_SUFFIX) $(1).mod.o -r -o $$@
+endef
+
+kernel-modpost-versions: $(wildcard $(LINUX_DIR)/Module.symvers)
+       @$(QUIET_CMD_ECHO) "  MODPOST    $(KERN_MODPOST_DIR)"
+       @echo  >$(KERN_MODPOST_DIR)/modpost-running
+       @rm -f $(KERN_MODPOST_DIR)/module-changes
+       $(Q) $(KERN_MODPOST) $(MODPOST_OPTS) $(MODULES_LIST:%=%$(KERN_LINK_SUFFIX))
+
+$(MODULES_LIST:%=%.mod.c) : kernel-modpost-versions
+
+kernel-modpost-pass-local: $(MODULES_LIST:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX))
+       @rm -f $(KERN_MODPOST_DIR)/modpost-running
+
+$(foreach module,$(MODULES_LIST),$(eval $(call MODPOST_kern_template,$(module),$(module:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX)))))
+
+endif
+
+-include $(KERN_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+
+# Kernel requires its own set of configuration header-files
+ifneq ($(kernel_LIBRARIES)$(rtlinux_LIBRARIES)$(kernel_MODULES)$(rtlinux_MODULES)$(kernel_HEADERS)$(rtlinux_HEADERS)$(kernel_HEADERS)$(rtlinux_HEADERS)$(nobase_kernel_HEADERS)$(nobase_rtlinux_HEADERS)$(renamed_kernel_HEADERS)$(renamed_rtlinux_HEADERS),)
+KERN_CONFIG_HEADERS_REQUIRED = y
+endif
+
+$(eval $(call omk_pass_template, kernel-lib-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_LIBRARIES)$(rtlinux_LIBRARIES)))
+$(eval $(call omk_pass_template, kernel-mod-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_MODULES)$(rtlinux_MODULES)))
+
+kernel-modpost-pass:
+       +@if [ -e "$(KERN_MODPOST_DIR)/module-changes" -o -e "$(KERN_MODPOST_DIR)/modpost-running" ] ; \
+       then \
+           $(MAKE) --no-print-directory -C $(KERN_MODPOST_DIR) \
+              -f $(SOURCES_DIR)/Makefile KERN_RULE_TEMPLATES=y KERN_MODPOST_PASS=y $(@:%=%-local) ; \
+       fi
+
+$(eval $(call omk_pass_template, library-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(lib_LIBRARIES)$(shared_LIBRARIES)))
+$(eval $(call omk_pass_template, binary-pass, $(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(bin_PROGRAMS)$(utils_PROGRAMS)$(test_PROGRAMS)))
+
+$(eval $(call omk_pass_template,clean,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,install,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,include-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,always))
+
+check-dir::
+       @$(call mkdir_def,$(USER_BUILD_DIR))
+       @$(call mkdir_def,$(KERN_BUILD_DIR))
+       @$(call mkdir_def,$(USER_INCLUDE_DIR))
+       @$(call mkdir_def,$(KERN_INCLUDE_DIR))
+       @$(call mkdir_def,$(USER_LIB_DIR))
+       @$(call mkdir_def,$(KERN_LIB_DIR))
+       @$(call mkdir_def,$(USER_BIN_DIR))
+       @$(call mkdir_def,$(USER_UTILS_DIR))
+       @$(call mkdir_def,$(USER_TESTS_DIR))
+       @$(call mkdir_def,$(KERN_MODULES_DIR))
+       @$(call mkdir_def,$(KERN_MODPOST_DIR))
+
+install-local:                 # TODO
+
+$(eval $(call include-pass-template,$(USER_INCLUDE_DIR),include))
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),kernel))
+ifeq ($(CONFIG_RTLINUX),y)
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),rtlinux))
+endif
+
+
+ifdef USER_RULE_TEMPLATES
+
+# User-space static libraries and applications object files
+
+USER_SOURCES := $(sort $(USER_SOURCES))
+
+USER_GEN_SOURCES := $(sort $(USER_GEN_SOURCES))
+
+#$(warning USER_SOURCES = $(USER_SOURCES))
+
+$(foreach src,$(filter %.c,$(USER_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+
+$(foreach src,$(filter %.c,$(USER_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.o),)))
+
+# User-space shared libraries object files
+
+SOLIB_SOURCES := $(sort $(SOLIB_SOURCES))
+
+SOLIB_GEN_SOURCES := $(sort $(SOLIB_GEN_SOURCES))
+
+#$(warning SOLIB_SOURCES = $(SOLIB_SOURCES))
+#$(warning SOLIB_GEN_SOURCES = $(SOLIB_GEN_SOURCES))
+
+$(foreach src,$(filter %.c,$(SOLIB_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cc,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cxx,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.S,$(SOLIB_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.c,$(SOLIB_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+# Create _build directories for sources in subdirectories i.e. *_SOURCES=dir/file.c
+_dirs_to_create=$(filter-out ./,$(sort $(dir $(USER_SOURCES) $(SOLIB_SOURCES))))
+ifneq ($(_dirs_to_create),)
+$(shell mkdir -p $(addprefix $(LOCAL_BUILD_DIR)/,$(_dirs_to_create)))
+endif
+
+# IDL compilation
+
+USER_IDLS := $(sort $(USER_IDLS))
+
+$(foreach src,$(filter %.idl,$(USER_IDLS)),$(eval $(call COMPILE_idl_template,$(SOURCES_DIR)/$(src),$(src:%.idl=%))))
+
+endif
+
+ifdef KERN_RULE_TEMPLATES
+
+KERN_SOURCES := $(sort $(KERN_SOURCES))
+
+#$(warning KERN_SOURCES = $(KERN_SOURCES))
+
+$(foreach src,$(filter %.c,$(KERN_SOURCES)),$(eval $(call COMPILE_c_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+endif
+
+clean-local: clean-custom
+       @echo Cleaning in $(KERN_OBJS_DIR) and $(USER_OBJS_DIR)
+       @rm -f $(KERN_OBJS_DIR)/*.o $(USER_OBJS_DIR)/*.[och] $(USER_OBJS_DIR)/*.lo\
+              $(KERN_OBJS_DIR)/*.d $(USER_OBJS_DIR)/*.d \
+              $(KERN_OBJS_DIR)/*.map $(USER_OBJS_DIR)/*.map \
+              $(KERN_OBJS_DIR)/*.mod.c \
+              $(kernel_MODULES:%=$(KERN_MODPOST_DIR)/%.*) \
+              $(LOCAL_CONFIG_H:%=$(KERN_OBJS_DIR)/%) \
+              $(LOCAL_CONFIG_H:%=$(USER_OBJS_DIR)/%)
+       @if [ -e $(KERN_LIB_DIR)/kernel.mk ] ; then \
+           touch -t 200001010101 $(KERN_LIB_DIR)/kernel.mk ; \
+       fi
+
+include-pass-submakes: extra-rules-subdirs
+
+# We must go to EXTRA_RULES_SUBDIRS before going to any other
+# directory, since the executables compiled in EXTRA_RULES_SUBDIRS
+# might be needed there.
+include-pass-this-dir $(foreach subdir,$(SUBDIRS),include-pass-$(subdir)-subdir): extra-rules-subdirs
+
+default: include-pass library-pass binary-pass
+ifndef OMIT_KERNEL_PASSES
+# Also make kernel passes if not disabled
+default: kernel-lib-pass kernel-pass
+endif
+                                                                                 #OMK:config_h.omk@Makefile.rules.linux
+# Syntax: $(call BUILD_CONFIG_H_template,<stamp_dir>,<header_file_path>,<list_of_options_to_export>,<header_barrier>)
+define BUILD_CONFIG_H_template
+
+$(addprefix $(1)/,$(notdir $(addsuffix .stamp,$(2)))) : $(CONFIG_FILES)
+       @$(QUIET_CMD_ECHO) "  CONFGEN $(notdir $(2))"
+       @if [ ! -d `dirname $(2).tmp` ] ; then \
+               mkdir -p `dirname $(2).tmp` ; fi
+       @echo "/* Automatically generated from */" > "$(2).tmp"
+       @echo "/* config files: $$(^:$(OUTPUT_DIR)/%=%) */" >> "$(2).tmp"
+       $(if $(DOXYGEN),@echo "/** @file */" >> "$(2).tmp")
+       @echo "#ifndef $(4)" >> "$(2).tmp"
+       @echo "#define $(4)" >> "$(2).tmp"
+       @( $(foreach x, $(shell echo '$($(3))' | tr 'x\t ' 'x\n\n' | sed -e 's/^\([^ =]*\)\(=[^ ]\+\|\)$$/\1/' ), \
+               echo '$(x).$($(x))' ; ) echo ; ) | \
+               sed -e '/^[^.]*\.n$$$$/d' -e '/^[^.]*\.$$$$/d' -e 's/^\([^.]*\)\.[ym]$$$$/\1.1/' | \
+               sed -n -e 's/^\([^.]*\)\.\(.*\)$$$$/#define \1 \2/p' \
+                 >> "$(2).tmp"
+       @echo "#endif /*$(4)*/" >> "$(2).tmp"
+       @touch "$$@"
+       @if cmp --quiet "$(2).tmp" "$(2)" ; then rm "$(2).tmp"; \
+       else mv "$(2).tmp" "$(2)" ; \
+       echo "Updated configuration $(2)" ; fi
+
+endef
+
+ifdef LOCAL_CONFIG_H
+
+# This must be declared after the default cflags are assigned!
+# Override is used to override command line assignemnt.
+override CFLAGS += -I $(USER_OBJS_DIR)
+override kernel_INCLUDES += -I $(KERN_OBJS_DIR)
+$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(USER_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+
+endif
+
+# Special rules for configuration exported headers
+
+#FIXME: The directory for headers should not be specified here.
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(addprefix $(USER_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+config_h_stamp_files = $(addprefix $(USER_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(config_h_stamp_files)
+
+ifneq ($(KERN_CONFIG_HEADERS_REQUIRED),)
+
+ifdef LOCAL_CONFIG_H
+$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(KERN_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+endif
+
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(addprefix $(KERN_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+kern_config_h_stamp_files = $(addprefix $(KERN_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(kern_config_h_stamp_files)
+
+endif
+
+clean-local: clean-local-config-h
+
+clean-local-config-h:
+       @$(foreach confh,$(config_h_stamp_files) $(kern_config_h_stamp_files),\
+           if [ -e $(confh) ] ; then rm $(confh) ; fi ; \
+       )
+                                                                                 #OMK:qt.omk@Makefile.rules.linux
+ifneq ($(QT_SUBDIRS)$(QT_PROJECTS),)
+
+# Usage: $(call qt_project_template,<.pro_file relative to SOURCES_DIR>)
+define qt_project_template
+
+.PHONY: qt-subpass-$(1) clean-qt-$(dir $(1))
+
+# FIXME: Handle multiple .pro files correctly
+$(LOCAL_BUILD_DIR)/$(dir $(1))Makefile: $(SOURCES_DIR)/$(1)
+       $(Q)mkdir -p $$(dir $$(@)) && cd $$(dir $$(@)) &&               \
+       $(if $(QMAKE),$(QMAKE),$(QTDIR:%=%/bin/)qmake)                  \
+            TOP_DIR=$(OUTPUT_DIR)                                      \
+            RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1))                 \
+            $(QTDIR:%=QTDIR=%) CC=$(CC) CXX=$(CXX)                     \
+            LIBS+="-L$(USER_LIB_DIR)" DESTDIR=$(USER_BIN_DIR)          \
+            INCLUDEPATH+="$(USER_INCLUDE_DIR)"                         \
+            QMAKE_LFLAGS="-Wl,-rpath-link,$(USER_LIB_DIR) $$(QMAKE_LFLAGS)" \
+            $(SOURCES_DIR)/$(1)
+
+# This horrible substitution is here to properly escape
+# -Wl,-rpath,$ORIGIN flags. It includes escaping for make, shell,
+# qmake and again make and shell run on qmake generated makefile.
+QMAKE_LFLAGS = $$(subst $$$$,\\\\\\$$$$\$$$$,$$(LDFLAGS))
+
+# Hook to binary pass
+binary-pass-submakes: qt-subpass-$(1)
+qt-subpass-$(1): $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+       $(Q)$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir $(1)) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1)) -C $(LOCAL_BUILD_DIR)/$(dir $(1)) || exit 1 ;
+
+# Hook to clean pass
+clean-local: clean-qt-$(dir $(1))
+clean-qt-$(dir $(1)): $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+       @$(QUIET_CMD_ECHO) "  QT CLEAN $(dir $(1))"
+       $(Q)$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir $(1)) \
+         RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1)) \
+         -C $(LOCAL_BUILD_DIR)/$(dir $(1)) clean
+       $(Q)rm $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+endef
+
+$(foreach pro,$(QT_PROJECTS), $(eval $(call qt_project_template,$(pro))))
+$(foreach pro,$(foreach dir,$(QT_SUBDIRS), $(wildcard $(dir)/*.pro)), $(eval $(call qt_project_template,$(pro))))
+
+endif
+                                                                                 #OMK:sources-list.omk@Makefile.rules.linux
+# Rules that creates the list of files which are used during
+# compilation. The list reflects conditional compilation depending on
+# config.omk and other variables.
+
+SOURCES_LIST_FN=sources.txt
+ifndef SOURCES_LIST
+SOURCES_LIST_DIR:=$(RELATIVE_DIR)
+SOURCES_LIST:=$(OUTPUT_DIR)/$(SOURCES_LIST_DIR)/$(SOURCES_LIST_FN)
+SOURCES_LIST_D := $(LOCAL_BUILD_DIR)/$(SOURCES_LIST_FN).d
+export SOURCES_LIST SOURCES_LIST_DIR SOURCES_LIST_D
+endif
+
+ifneq ($(filter sources-list TAGS tags cscope,$(MAKECMDGOALS)),)
+NEED_SOURCES_LIST=y
+endif
+
+ifeq ($(NEED_SOURCES_LIST),y) # avoid execution of find command bellow if it is not useful
+.PHONY: sources-list
+sources-list: $(SOURCES_LIST)
+
+$(SOURCES_LIST): $(CONFIG_FILES) $(shell find -name $(MAKEFILE_OMK))
+       @$(call mkdir_def,$(dir $(SOURCES_LIST_D)))
+       @echo -n "" > "$(SOURCES_LIST).tmp"
+       @echo -n "" > "$(SOURCES_LIST_D).tmp"
+       @$(MAKE) --no-print-directory sources-list-pass
+       @echo "# Automatically generated list of files in '$(RELATIVE_DIR)' that are used during OMK compilation" > "$(SOURCES_LIST).tmp2"
+       @cat "$(SOURCES_LIST).tmp"|sort|uniq >> "$(SOURCES_LIST).tmp2"
+       @rm "$(SOURCES_LIST).tmp"
+       @mv "$(SOURCES_LIST).tmp2" "$(SOURCES_LIST)"
+       @echo "$(SOURCES_LIST): \\" > "$(SOURCES_LIST_D).tmp2"
+       @cat "$(SOURCES_LIST_D).tmp"|grep -v "$(SOURCES_LIST_D).tmp"|sort|uniq|\
+               sed -e 's/$$/\\/' >> "$(SOURCES_LIST_D).tmp2"
+       @rm "$(SOURCES_LIST_D).tmp"
+       @mv "$(SOURCES_LIST_D).tmp2" "$(SOURCES_LIST_D)"
+endif
+
+$(eval $(call omk_pass_template,sources-list-pass,$$(LOCAL_BUILD_DIR),,always))
+
+sources-list-pass-local:
+       @$(foreach m,$(MAKEFILE_LIST),echo '  $(m)' >> "$(SOURCES_LIST_D).tmp";)
+       @$(foreach h,$(include_HEADERS) $(nobase_include_HEADERS) $(kernel_HEADERS),\
+         echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(h)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach ch,$(config_include_HEADERS), \
+         echo "$(USER_INCLUDE_DIR:$(OUTPUT_DIR)/$(addsuffix /,$(SOURCES_LIST_DIR))%=%)/$(ch)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach h,$(renamed_include_HEADERS),echo '$(h)'|sed -e 's|\(.*\)->.*|$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))\1|' >> "$(SOURCES_LIST).tmp";)
+       @$(foreach bin,$(lib_LIBRARIES) $(shared_LIBRARIES) $(bin_PROGRAMS) $(test_PROGRAMS) $(utils_PROGRAMS) \
+         $(kernel_LIBRARIES) $(rtlinux_LIBRARIES) $(kernel_MODULES),\
+         $(foreach src,$(filter-out %.o,$($(bin)_SOURCES)),echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(src)" >> "$(SOURCES_LIST).tmp";))
+
+############ TAGS ###########
+
+ifeq ($(MAKECMDGOALS),TAGS)
+ETAGS=etags
+TAGS_CMD = $(ETAGS)
+TAGS: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+ifeq ($(MAKECMDGOALS),tags) 
+CTAGS=ctags -N
+TAGS_CMD = $(CTAGS)
+tags: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+export TAGS_CMD
+
+ifeq ($(MAKECMDGOALS),do-tags)
+.PHONY: do-tags
+do-tags: $(shell sed -e '/^\#/d' $(SOURCES_LIST))
+       @$(QUIET_CMD_ECHO) "  TAGS    $(SOURCES_LIST_FN)"
+       $(Q)$(TAGS_CMD) $^
+endif
+
+############ CSCOPE ###########
+
+cscope: $(SOURCES_LIST)
+       @$(QUIET_CMD_ECHO) "  CSCOPE  < $(SOURCES_LIST_FN)"
+       $(Q)sed -e '/^#/d' $(SOURCES_LIST) > cscope.files
+       $(Q)cscope -b -icscope.files
+#FIXME: see doc to -i in cscope(1)
diff --git a/build/aquosa/config.target b/build/aquosa/config.target
new file mode 100644 (file)
index 0000000..864d30e
--- /dev/null
@@ -0,0 +1,72 @@
+# -*- makefile -*-
+# Config file for compilation by OMK for AQuoSA/Linux OS target
+
+# You can override these variables in config.omk
+AQUOSA_ROOT ?= $(wildcard /usr/local/aquosa)
+QTDIR ?= $(wildcard /usr/share/qt4)
+
+test: wvtest
+.PHONY: test
+
+export PLATFORM=AQuoSA
+
+# Create symbolic links to headers instead of copying them. Useful
+# during development.
+LN_HEADERS=y
+
+# We do not want to overwrite original FRESCOR Makefiles
+USE_LEAF_MAKEFILES=n
+
+OMIT_KERNEL_PASSES=y
+
+########################################
+# Setting of compiler
+########################################
+
+# Instead, we call normal gcc with parameters which mgcc adds
+
+CFLAGS=$(ARCH_GCC_OPTS) -fpic -Wall -Wuninitialized -g -O1 -D_REENTRANT -D$(PLATFORM) -D_XOPEN_SOURCE=600 -D_BSD_SOURCE
+LDFLAGS=$(ARCH_LD_OPTS) $(LIBS_PATH) $(LIBS)
+LDFLAGS += '-Wl,-rpath,$$ORIGIN/../lib' -z origin --enable-new-dtags
+
+IDL_COMPILER = $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin/forb-idl
+
+# Other config
+FRSH_DISTRIBUTED_MODULE_SUPPORTED=true
+CONFIG_FORB_PROTO_UNIX=n
+CONFIG_FORB_PROTO_INET_DEFAULT=y
+
+# Disable tests which do not compile with FRSH_FORB
+
+CONFIG_FRSH_TEST_context_switch=n                            # Needs timespec_operations.h and frsh_os_compatibility.h
+CONFIG_FRSH_TEST_demo_september2007=n                        # Needs frsh_thread_get_vres_id()
+CONFIG_FRSH_TEST_demo_september2007_with_signals=n           # Some problem with signal constants and non-int vres_id
+CONFIG_FRSH_TEST_dl_test=n                                   # Needs different Makefile.omk
+CONFIG_FRSH_TEST_example_d-ac1_frescor=n                     # Needs int vres_id
+CONFIG_FRSH_TEST_frsh_shared_obj_test=n                      # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_functions=n                                 # Needs timespec_operations.h and frsh_os_compatibility.h
+CONFIG_FRSH_TEST_jitter_test=n                                       # Needs timespec_operations.h and frsh_os_compatibility.h
+CONFIG_FRSH_TEST_sharedobj_prototype=n                               # Needs frsh_sharedobj_XXX
+CONFIG_FRSH_TEST_test_bind=n                                 # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_contract_labels=n                      # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_eat=n                                  # Needs eat.h
+CONFIG_FRSH_TEST_test_frsh_performance=n                     # Needs more frsh api - todo
+CONFIG_FRSH_TEST_test_frsh_renegotiate_async=n                       # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_frsh_synch_obj=n                               # Needs frsh_thread_id_t to be simple type - Aquosa declares it as structure
+CONFIG_FRSH_TEST_test_memory=n                                       # Needs different Makefile.omk and then we will see :)
+CONFIG_FRSH_TEST_demo_sept07_negotiate_and_send=n            # Needs RTEP
+CONFIG_FRSH_TEST_demo_sept07_negotiations_limit=n            # Needs RTEP
+CONFIG_FRSH_TEST_demo_sept07_renegotiate_and_send=n          # Needs RTEP
+CONFIG_FRSH_TEST_test_endpoints=n                            # Needs RTEP
+CONFIG_FRSH_TEST_test_frsh_distributed_contract_negotiate=n   # Nedds vres_id to be int
+CONFIG_FRSH_TEST_test_frsh_distributed_contract_renegotiate=n # Needs RTEP
+CONFIG_FRSH_TEST_test_frsh_distributed_init=n                # Needs THE_FRSH_CPU_ID
+CONFIG_FRSH_TEST_test_frsh_marshal=n                         # Accesses frsh_contract_t fields directly
+CONFIG_FRSH_TEST_test_frsh_send_receive_basic=n              # Needs RTEP
+CONFIG_FRSH_TEST_test_get_network_info=n                     # Needs RTEP
+CONFIG_FRSH_TEST_test_self_bind=n                            # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_sizes=n                                # Needs frsh_internal.h - TODO
+CONFIG_FRSH_TEST_test_spare_capacity=n                               # Needs more frsh api - TODO
+CONFIG_FRSH_TEST_test_timespec_operations=n                  # Needs timespec_operations.h
+CONFIG_FRSH_TEST_test_vres_id_bits=n                         # Depends on bit-fields in integer vres_id
+CONFIG_FSA_TESTS=n                                           # Depends on bit-fields in integer vres_id
diff --git a/build/aquosa/create-links b/build/aquosa/create-links
new file mode 100755 (executable)
index 0000000..b9fd523
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Usage: ./create-links [path/to/frescor/root]
+#
+# path/to/frescor/root defaults to ../..
+
+LINKS="
+fna
+forb
+fosa
+frsh
+frsh_forb
+fwp/fwp
+ulut
+utils
+"
+
+FRESCOR_SRC=${1:-../..}
+
+for link in $LINKS; do
+       ln -s $FRESCOR_SRC/$link .
+done
+
diff --git a/build/aquosa/fna b/build/aquosa/fna
new file mode 120000 (symlink)
index 0000000..75492d5
--- /dev/null
@@ -0,0 +1 @@
+../../src/fna
\ No newline at end of file
diff --git a/build/aquosa/forb b/build/aquosa/forb
new file mode 120000 (symlink)
index 0000000..8aab5ae
--- /dev/null
@@ -0,0 +1 @@
+../../src/forb
\ No newline at end of file
diff --git a/build/aquosa/fosa b/build/aquosa/fosa
new file mode 120000 (symlink)
index 0000000..d63c04c
--- /dev/null
@@ -0,0 +1 @@
+../../src/fosa
\ No newline at end of file
diff --git a/build/aquosa/frsh b/build/aquosa/frsh
new file mode 120000 (symlink)
index 0000000..ade6dfd
--- /dev/null
@@ -0,0 +1 @@
+../../src/frsh
\ No newline at end of file
diff --git a/build/aquosa/frsh-forb-demo.sh b/build/aquosa/frsh-forb-demo.sh
new file mode 100755 (executable)
index 0000000..163b61c
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh -x
+
+[ -d _compiled/bin ] && PATH=_compiled/bin:$PATH
+
+fcb&
+FCB_PID=$!
+sleep 1
+frm_gui &
+GUI_PID=$!
+frm_dummy &
+DUMMY_PID=$!
+sleep 1
+dummy_spare_capacity &
+S1=$!
+dummy_renegotiation &
+R1=$!
+sleep 1
+dummy_renegotiation &
+R1=$!
+frm_fwp &
+FWP_PID=$!
+wait $GUI_PID
+kill $FWP_PID $DUMMY_PID $FCB_PID $R1 $R2 $S1
diff --git a/build/aquosa/frsh-include b/build/aquosa/frsh-include
new file mode 120000 (symlink)
index 0000000..087eb78
--- /dev/null
@@ -0,0 +1 @@
+../../src/frsh-include
\ No newline at end of file
diff --git a/build/aquosa/fwp b/build/aquosa/fwp
new file mode 120000 (symlink)
index 0000000..e12793f
--- /dev/null
@@ -0,0 +1 @@
+../../src/fwp/fwp
\ No newline at end of file
diff --git a/build/aquosa/kernelcfg2mk b/build/aquosa/kernelcfg2mk
new file mode 100755 (executable)
index 0000000..3fd50d2
--- /dev/null
@@ -0,0 +1,217 @@
+#!/bin/bash
+
+if [ $# -lt 1 ] ; then
+  echo "kernelcfg2mk: requires linux kernel directory as the first argument"
+  exit 2
+fi
+
+LINUX_DIR="$1"
+
+if [ $# -gt 1 ] ; then
+  KERN_MODULES_DIR="$2"
+fi
+
+if [ ! -e $LINUX_DIR/.config ] ; then
+  echo "kernelcfg2mk: the provided locations doesnot point to configured kernel sources"
+  echo "        check directory $LINUX_DIR"
+  exit 2
+fi
+
+if [ ! -e $LINUX_DIR/.config ] ; then
+  echo "kernelcfg2mk: the provided locations doesnot point to configured kernel sources"
+  echo "        check directory $LINUX_DIR"
+  exit 2
+fi
+
+if [ -z "$KERN_BUILD_DIR" ]  ; then
+  KERN_BUILD_DIR=`pwd`
+fi
+
+if [ -z "$KERN_MODULES_DIR" ]  ; then
+  KERN_MODULES_DIR=`pwd`
+fi
+
+
+if [ -z "$MAKE" ]  ; then
+  MAKE="make"
+fi
+
+
+KERN_TEST_DIR="$KERN_BUILD_DIR/kern-test-mk"
+
+mkdir -p $KERN_TEST_DIR
+
+#echo MAKERULES_DIR $MAKERULES_DIR
+#echo LINUX_DIR $LINUX_DIR
+#echo KERN_BUILD_DIR $KERN_BUILD_DIR
+#echo KERN_MODULES_DIR $KERN_MODULES_DIR
+
+RETVAL="0"
+
+LINUX_VERSION=$(grep UTS_RELEASE ${LINUX_DIR}/include/linux/version.h | \
+               sed 's/[^"]*"\(.*\)\{1\}"/\1/')
+if [ -z "$LINUX_VERSION" ] ; then
+  LINUX_VERSION=$(grep UTS_RELEASE ${LINUX_DIR}/include/linux/utsrelease.h | \
+                 sed 's/[^"]*"\(.*\)\{1\}"/\1/')
+fi
+if [ -z "$LINUX_VERSION" ] ; then
+  LINUX_VERSION=$(grep UTS_RELEASE ${LINUX_DIR}/include/generated/utsrelease.h | \
+                 sed 's/[^"]*"\(.*\)\{1\}"/\1/')
+fi
+
+LINUX_VERSION_MAJOR=$(echo ${LINUX_VERSION} | cut -d. -f1)
+LINUX_VERSION_MINOR=$(echo ${LINUX_VERSION} | cut -d. -f2)
+
+#echo $LINUX_VERSION
+#echo $LINUX_VERSION_MAJOR
+#echo $LINUX_VERSION_MINOR
+
+
+case $LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR in
+
+
+#=====================================================================
+# test for 2.4.x kernels
+    2.[01234])
+
+       rm -f ${KERN_BUILD_DIR}/kernel.mk
+       rm -rf ${KERN_TEST_DIR}
+       mkdir ${KERN_TEST_DIR}
+       if [ $? -ne 0 ] ; then
+               echo "Cannot create Linux kernel test build directory \"${KERN_TEST_DIR}\""
+               exit 3
+       fi
+       cd ${KERN_TEST_DIR}
+
+       cat >${KERN_TEST_DIR}/Makefile <<EOF
+
+.PHONY: modules
+modules:
+       @echo LINUX_ARCH="\$(ARCH)" >>flags
+       @echo LINUX_LDFLAGS="" >>flags
+       @echo LINUX_ARFLAGS="\$(ARFLAGS)" >>flags
+       @echo LINUX_CROSS_COMPILE="\$(CROSS_COMPILE)" >>flags
+       @echo LINUX_KERNELRELEASE="\$(KERNELRELEASE)" >>flags
+       @echo LINUX_AFLAGS="\$(AFLAGS)" | sed 's#Iinclude#I"\$(LINUXDIR)/include"#g'>>flags
+       @echo LINUX_CFLAGS="\$(CFLAGS)" | sed 's#Iinclude#I"\$(LINUXDIR)/include"#g'>>flags
+       @echo LINUX_MODFLAGS="\$(MODFLAGS)"
+       @echo LINUX_CC="\$(CC)" >>flags
+       @echo LINUX_LD="\$(LD) \$(LDFLAGS)" >>flags
+       @echo LINUX_AS="\$(AS)" >>flags
+       @echo LINUX_AR="\$(AR)" >>flags
+       @echo LINUX_MODULE_EXT=".o" >>flags
+
+EOF
+
+       #echo ${MAKE} -C ${LINUX_DIR} SUBDIRS=${KERN_TEST_DIR} modules
+       ${MAKE} -C ${LINUX_DIR} SUBDIRS=${KERN_TEST_DIR} modules
+       if [ $? == 0 ] ; then
+               cp -v flags ${KERN_MODULES_DIR}/kernel.mk       
+               if [ ! $? == 0 ] ; then
+                       RETVAL="2"
+               fi
+       else
+               RETVAL="1"
+       fi
+
+       cd ${KERN_BUILD_DIR}
+       rm -rf ${KERN_TEST_DIR}
+       ;;
+
+#=====================================================================
+# test for 2.6.x kernels
+
+    2.6)
+
+       rm -f ${KERN_BUILD_DIR}/kernel.mk
+       rm -rf ${KERN_TEST_DIR}
+       mkdir ${KERN_TEST_DIR}
+       if [ $? -ne 0 ] ; then
+               echo "Cannot create Linux kernel test build directory \"${KERN_TEST_DIR}\""
+               exit 3
+       fi
+       cd ${KERN_TEST_DIR}
+
+       cat >${KERN_TEST_DIR}/Makefile <<EOF
+obj-m += fake.o
+
+\$(obj)/fake.c: flags
+       touch \$(obj)/fake.c
+
+ifeq (\$(KBUILD_SRC),)
+OMK_LINUX_SRC = \$(LINUXDIR)
+else
+OMK_LINUX_SRC = \$(KBUILD_SRC)
+endif
+#\$(warning Test \$OMK_LINUX_SRC)
+
+.PHONY: flags
+flags:
+       @echo LINUX_SRC="\$(OMK_LINUX_SRC)" >>\$(obj)/flags
+       @echo LINUX_ARCH="\$(ARCH)" >>\$(obj)/flags
+       @echo LINUX_BUILDHOST="\$(KBUILD_BUILDHOST)" >>\$(obj)/flags
+       @echo LINUX_LDFLAGS="" >>\$(obj)/flags
+       @echo LINUX_ARFLAGS="\$(ARFLAGS)" >>\$(obj)/flags
+       @echo LINUX_CROSS_COMPILE="\$(CROSS_COMPILE)" >>\$(obj)/flags
+       @echo LINUX_KERNELRELEASE="\$(KERNELRELEASE)" >>\$(obj)/flags
+ifdef KBUILD_CFLAGS
+       @echo LINUX_CPPFLAGS="\$(KBUILD_CPPFLAGS)\$(if \$(filter -I,\$(KBUILD_CPPFLAGS)),, \$(LINUXINCLUDE))" | sed 's#-I\(include\|arch\)#-I"\$(LINUXDIR)/\1"#g'>>\$(obj)/flags
+       @echo LINUX_AFLAGS="\$(KBUILD_AFLAGS)" | sed 's#-I\(include\|arch\)#-I"\$(OMK_LINUX_SRC)/\1"#g'>>\$(obj)/flags
+       @echo LINUX_CFLAGS="\$(KBUILD_CFLAGS)" | sed 's#-I\(include\|arch\)#-I"\$(OMK_LINUX_SRC)/\1"#g'>>\$(obj)/flags
+else
+       @echo LINUX_CPPFLAGS="\$(CPPFLAGS)" | sed 's#Iinclude#I"\$(LINUXDIR)/include"#g'>>\$(obj)/flags
+       @echo LINUX_AFLAGS="\$(AFLAGS)" | sed 's#Iinclude#I"\$(OMK_LINUX_SRC)/include"#g'>>\$(obj)/flags
+       @echo LINUX_CFLAGS="\$(CFLAGS)" | sed 's#Iinclude#I"\$(OMK_LINUX_SRC)/include"#g'>>\$(obj)/flags
+endif
+       @echo LINUX_CFLAGS_MODULE="\$(CFLAGS_MODULE)" >>\$(obj)/flags
+       @echo LINUX_CC="\$(CC)" >>\$(obj)/flags
+       @echo LINUX_LD="\$(LD) \$(LDFLAGS) \$(LDFLAGS_MODULE)" | sed 's#\(\<arch/[^ ]*\.o\>\)#"\$(LINUXDIR)/\1"#g' >>\$(obj)/flags
+       @echo LINUX_AS="\$(AS)" >>\$(obj)/flags
+       @echo LINUX_AR="\$(AR)" >>\$(obj)/flags
+       @echo LINUX_MODULE_EXT=".ko" >>\$(obj)/flags
+       @echo LINUX_QUOTE_MODNAME=\$(if \$(findstring KBUILD_STR,\$(basename_flags)),y,) >>\$(obj)/flags
+       @echo LINUX_CONFIG_MODVERSIONS=\$(CONFIG_MODVERSIONS) >>\$(obj)/flags
+       @echo LINUX_CONFIG_MODULE_SRCVERSION_ALL=\$(CONFIG_MODULE_SRCVERSION_ALL) >>\$(obj)/flags
+       @echo LINUX_CONFIG_DEBUG_SECTION_MISMATCH=\$(CONFIG_DEBUG_SECTION_MISMATCH) >>\$(obj)/flags
+       @echo LINUX_CONFIG_MARKERS=\$(CONFIG_MARKERS) >>\$(obj)/flags
+       @echo LINUX_KBUILD_EXTMOD=\$(KBUILD_EXTMOD) >>\$(obj)/flags
+       @echo LINUX_KBUILD_EXTRA_SYMBOLS=\$(KBUILD_EXTRA_SYMBOLS) >>\$(obj)/flags
+       @echo LINUX_KBUILD_MODPOST_WARN=\$(KBUILD_MODPOST_WARN) >>\$(obj)/flags
+       @echo LINUX_CROSS_BUILD=\$(cross_build) >>\$(obj)/flags
+EOF
+
+       # modkern_cflags := $(CFLAGS_KERNEL) / $(CFLAGS_MODULE)
+
+       # _c_flags       = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
+       # _a_flags       = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
+       # _cpp_flags     = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
+
+       # export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
+       # export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+       # export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
+
+       #  -p V=1
+       #echo ${MAKE} -C ${LINUX_DIR} SUBDIRS=${KERN_TEST_DIR} LINUXDIR=${LINUX_DIR} MODVERDIR=${KERN_TEST_DIR} modules
+       ${MAKE} -C ${LINUX_DIR} M=${KERN_TEST_DIR} LINUXDIR=${LINUX_DIR} MODVERDIR=${KERN_TEST_DIR}/modver modules
+       #if [ $? == 0 ] ; then
+               cp -v flags ${KERN_MODULES_DIR}/kernel.mk       
+               if [ ! $? == 0 ] ; then
+                       RETVAL="2"
+               fi
+       #else
+       #       RETVAL="1"
+       #fi
+
+       cd ${KERN_BUILD_DIR}
+       rm -rf ${KERN_TEST_DIR}
+       ;;
+
+#=====================================================================
+
+    *)
+       echo "Unsupported Linux version $LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR"
+    ;;
+esac
+
+
+exit ${RETVAL}
diff --git a/build/aquosa/ulut b/build/aquosa/ulut
new file mode 120000 (symlink)
index 0000000..77b914d
--- /dev/null
@@ -0,0 +1 @@
+../../src/ulut/ulut
\ No newline at end of file
diff --git a/build/aquosa/wvtest/c/Makefile b/build/aquosa/wvtest/c/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/build/aquosa/wvtest/c/Makefile.omk b/build/aquosa/wvtest/c/Makefile.omk
new file mode 100644 (file)
index 0000000..6614b78
--- /dev/null
@@ -0,0 +1,7 @@
+
+include_HEADERS = wvtest.h
+
+CFLAGS += -DWVTEST_CONFIGURED
+
+lib_LIBRARIES = wvtest
+wvtest_SOURCES = wvtestmain.c wvtest.c wvtestfrsh.c
diff --git a/build/aquosa/wvtest/c/wvtest.c b/build/aquosa/wvtest/c/wvtest.c
new file mode 100644 (file)
index 0000000..ecbfbf7
--- /dev/null
@@ -0,0 +1,394 @@
+/*
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#ifdef _WIN32
+#include <direct.h>
+#else
+#include <unistd.h>
+#include <sys/wait.h>
+#endif
+#include <errno.h>
+#include <signal.h>
+
+#include <stdlib.h>
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+# include <valgrind/memcheck.h>
+# include <valgrind/valgrind.h>
+#else
+# define VALGRIND_COUNT_ERRORS 0
+# define VALGRIND_DO_LEAK_CHECK
+# define VALGRIND_COUNT_LEAKS(a,b,c,d) (a=b=c=d=0)
+#endif
+
+#define MAX_TEST_TIME 40     // max seconds for a single test to run
+#define MAX_TOTAL_TIME 120*60 // max seconds for the entire suite to run
+
+#define TEST_START_FORMAT "! %s:%-5d %-40s "
+
+static int fails, runs;
+static time_t start_time;
+static bool run_twice;
+    
+static void alarm_handler(int sig);
+   
+static int memerrs()
+{
+    return (int)VALGRIND_COUNT_ERRORS;
+}
+
+static int memleaks()
+{
+    int leaked = 0, dubious = 0, reachable = 0, suppressed = 0;
+    VALGRIND_DO_LEAK_CHECK;
+    VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
+    printf("memleaks: sure:%d dubious:%d reachable:%d suppress:%d\n",
+          leaked, dubious, reachable, suppressed);
+    fflush(stdout);
+    
+    // dubious+reachable are normally non-zero because of globals...
+    // return leaked+dubious+reachable;
+    return leaked;
+}
+
+// Return 1 if no children are running or zombies, 0 if there are any running
+// or zombie children.
+// Will wait for any already-terminated children first.
+// Passes if no rogue children were running, fails otherwise.
+// If your test gets a failure in here, either you're not killing all your
+// children, or you're not calling waitpid(2) on all of them.
+static bool no_running_children()
+{
+#ifndef _WIN32
+    pid_t wait_result;
+
+    // Acknowledge and complain about any zombie children
+    do 
+    {
+       int status = 0;
+        wait_result = waitpid(-1, &status, WNOHANG);
+
+        if (wait_result > 0)
+        {
+            char buf[256];
+            snprintf(buf, sizeof(buf) - 1, "%d", wait_result);
+            buf[sizeof(buf)-1] = '\0';
+            WVFAILEQ("Unclaimed dead child process", buf);
+        }
+    } while (wait_result > 0);
+        
+    // There should not be any running children, so waitpid should return -1
+    WVPASS(errno == ECHILD);
+    WVPASS(wait_result == -1);
+    return (wait_result == -1 && errno == ECHILD);
+#endif
+    return true;
+}
+
+
+static void alarm_handler(int sig)
+{
+    printf("\n! WvTest  Current test took longer than %d seconds!  FAILED\n",
+          MAX_TEST_TIME);
+    fflush(stdout);
+    abort();
+}
+
+
+static const char *pathstrip(const char *filename)
+{
+    const char *cptr;
+    cptr = strrchr(filename, '/');
+    if (cptr) filename = cptr + 1;
+    cptr = strrchr(filename, '\\');
+    if (cptr) filename = cptr + 1;
+    return filename;
+}
+
+static bool prefix_match(const char *s, char * const *prefixes)
+{
+    char *const *prefix;
+    for (prefix = prefixes; prefix && *prefix; prefix++)
+    {
+       if (!strncasecmp(s, *prefix, strlen(*prefix)))
+           return true;
+    }
+    return false;
+}
+
+extern struct WvTest *__start_wvtest, *__stop_wvtest;
+
+int wvtest_run_all(char * const *prefixes)
+{
+    int old_valgrind_errs = 0, new_valgrind_errs;
+    int old_valgrind_leaks = 0, new_valgrind_leaks;
+    
+#ifdef _WIN32
+    /* I should be doing something to do with SetTimer here, 
+     * not sure exactly what just yet */
+#else
+    char *disable = getenv("WVTEST_DISABLE_TIMEOUT");
+    if (disable != NULL && disable[0] != '\0' && disable[0] != '0')
+        signal(SIGALRM, SIG_IGN);
+    else
+        signal(SIGALRM, alarm_handler);
+    alarm(MAX_TEST_TIME);
+#endif
+    start_time = time(NULL);
+    
+    // make sure we can always start out in the same directory, so tests have
+    // access to their files.  If a test uses chdir(), we want to be able to
+    // reverse it.
+    char wd[1024];
+    if (!getcwd(wd, sizeof(wd)))
+       strcpy(wd, ".");
+    
+    const char *slowstr1 = getenv("WVTEST_MIN_SLOWNESS");
+    const char *slowstr2 = getenv("WVTEST_MAX_SLOWNESS");
+    int min_slowness = 0, max_slowness = 65535;
+    if (slowstr1) min_slowness = atoi(slowstr1);
+    if (slowstr2) max_slowness = atoi(slowstr2);
+
+#ifdef _WIN32
+    run_twice = false;
+#else
+    char *parallel_str = getenv("WVTEST_PARALLEL");
+    if (parallel_str) 
+        run_twice = atoi(parallel_str) > 0;
+#endif
+
+    // there are lots of fflush() calls in here because stupid win32 doesn't
+    // flush very often by itself.
+    fails = runs = 0;
+    struct WvTest *cur, **p;
+    for (p = &__start_wvtest; p < &__stop_wvtest; p++)
+    {
+       cur = *p;
+       if (cur->slowness <= max_slowness
+           && cur->slowness >= min_slowness
+           && (!prefixes
+               || prefix_match(cur->idstr, prefixes)
+               || prefix_match(cur->descr, prefixes)))
+       {
+#ifndef _WIN32
+            // set SIGPIPE back to default, helps catch tests which don't set
+            // this signal to SIG_IGN (which is almost always what you want)
+            // on startup
+            signal(SIGPIPE, SIG_DFL);
+
+            pid_t child = 0;
+            if (run_twice)
+            {
+                // I see everything twice!
+                printf("Running test in parallel.\n");
+                child = fork();
+            }
+#endif
+
+           printf("\nTesting \"%s\" in %s:\n", cur->descr, cur->idstr);
+           fflush(stdout);
+           
+           cur->main();
+           chdir(wd);
+           
+           new_valgrind_errs = memerrs();
+           WVPASS(new_valgrind_errs == old_valgrind_errs);
+           old_valgrind_errs = new_valgrind_errs;
+           
+           new_valgrind_leaks = memleaks();
+           WVPASS(new_valgrind_leaks == old_valgrind_leaks);
+           old_valgrind_leaks = new_valgrind_leaks;
+           
+           fflush(stderr);
+           printf("\n");
+           fflush(stdout);
+
+#ifndef _WIN32
+            if (run_twice)
+            {
+                if (!child)
+                {
+                    // I see everything once!
+                    printf("Child exiting.\n");
+                    _exit(0);
+                }
+                else
+                {
+                    printf("Waiting for child to exit.\n");
+                    int result;
+                    while ((result = waitpid(child, NULL, 0)) == -1 && 
+                            errno == EINTR)
+                        printf("Waitpid interrupted, retrying.\n");
+                }
+            }
+#endif
+
+            WVPASS(no_running_children());
+       }
+    }
+    
+    WVPASS(runs > 0);
+    
+    if (prefixes && *prefixes && **prefixes)
+       printf("WvTest: WARNING: only ran tests starting with "
+              "specifed prefix(es).\n");
+    else
+       printf("WvTest: ran all tests.\n");
+    printf("WvTest: %d test%s, %d failure%s.\n",
+          runs, runs==1 ? "" : "s",
+          fails, fails==1 ? "": "s");
+    fflush(stdout);
+    
+    return fails != 0;
+}
+
+
+// If we aren't running in parallel, we want to output the name of the test
+// before we run it, so we know what happened if it crashes.  If we are
+// running in parallel, outputting this information in multiple printf()s
+// can confuse parsers, so we want to output everything in one printf().
+//
+// This function gets called by both start() and check().  If we're not
+// running in parallel, just print the data.  If we're running in parallel,
+// and we're starting a test, save a copy of the file/line/description until
+// the test is done and we can output it all at once.
+//
+// Yes, this is probably the worst API of all time.
+static void print_result_str(bool start, const char *_file, int _line, 
+                            const char *_condstr, const char *result)
+{
+    static char *file;
+    static char *condstr;
+    static int line;
+    char *cptr;
+    
+    if (start)
+    {
+        if (file) 
+            free(file);
+        if (condstr) 
+            free(condstr);
+        file = strdup(pathstrip(_file));
+        condstr = strdup(_condstr);
+        line = _line;
+
+        for (cptr = condstr; *cptr; cptr++)
+        {
+            if (!isprint((unsigned char)*cptr))
+                *cptr = '!';
+        }
+    }
+            
+    if (run_twice)
+    {
+        if (!start)
+            printf(TEST_START_FORMAT "%s\n", file, line, condstr, result);
+    }
+    else
+    {
+        if (start)
+            printf(TEST_START_FORMAT, file, line, condstr);
+        else
+            printf("%s\n", result);
+    }
+    fflush(stdout);
+
+    if (!start)
+    {
+        if (file)
+            free(file);
+        if (condstr)
+            free(condstr);
+        file = condstr = NULL;
+    }
+}
+
+static inline void
+print_result(bool start, const char *file, int line, 
+            const char *condstr, bool result)
+{
+       print_result_str(start, file, line, condstr, result ? "ok" : "FAILED");
+}
+
+void wvtest_start(const char *file, int line, const char *condstr)
+{
+    // Either print the file, line, and condstr, or save them for later.
+    print_result(true, file, line, condstr, false);
+}
+
+
+void wvtest_check(bool cond, const char *reason)
+{
+#ifndef _WIN32
+    alarm(MAX_TEST_TIME); // restart per-test timeout
+#endif
+    if (!start_time) start_time = time(NULL);
+    
+    if (time(NULL) - start_time > MAX_TOTAL_TIME)
+    {
+       printf("\n! WvTest   Total run time exceeded %d seconds!  FAILED\n",
+              MAX_TOTAL_TIME);
+       fflush(stdout);
+       abort();
+    }
+    
+    runs++;
+
+    print_result_str(false, NULL, 0, NULL, cond ? "ok" : (reason ? reason : "FAILED"));
+
+    if (!cond)
+    {
+       fails++;
+       
+       if (getenv("WVTEST_DIE_FAST"))
+           abort();
+    }
+}
+
+
+bool wvtest_start_check_eq(const char *file, int line,
+                           const char *a, const char *b, bool expect_pass)
+{
+    if (!a) a = "";
+    if (!b) b = "";
+    
+    size_t len = strlen(a) + strlen(b) + 8 + 1;
+    char str[len];
+    sprintf(str, "[%s] %s [%s]", a, expect_pass ? "==" : "!=", b);
+    
+    wvtest_start(file, line, str);
+    
+    bool cond = !strcmp(a, b);
+    if (!expect_pass)
+        cond = !cond;
+
+    wvtest_check(cond, NULL);
+    return cond;
+}
+
+
+bool wvtest_start_check_lt(const char *file, int line,
+                           const char *a, const char *b)
+{
+    if (!a) a = "";
+    if (!b) b = "";
+    
+    size_t len = strlen(a) + strlen(b) + 8 + 1;
+    char *str = malloc(len);
+    sprintf(str, "[%s] < [%s]", a, b);
+    
+    wvtest_start(file, line, str);
+    free(str);
+
+    bool cond = strcmp(a, b) < 0;
+    wvtest_check(cond, NULL);
+    return cond;
+}
diff --git a/build/aquosa/wvtest/c/wvtest.h b/build/aquosa/wvtest/c/wvtest.h
new file mode 100644 (file)
index 0000000..79c8da6
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- Mode: C -*-
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */ 
+#ifndef __WVTEST_H
+#define __WVTEST_H
+
+#ifndef WVTEST_CONFIGURED
+# error "Missing settings: HAVE_VALGRIND_MEMCHECK_H HAVE_WVCRASH WVTEST_CONFIGURED"
+#endif
+
+#include <time.h>
+#include <string.h>
+#include <stdbool.h>
+
+typedef void wvtest_mainfunc();
+
+struct WvTest {
+       const char *descr, *idstr;
+       wvtest_mainfunc *main;
+       int slowness;
+       struct WvTest *next;
+};
+
+int wvtest_run_all(char * const *prefixes);
+void wvtest_start(const char *file, int line, const char *condstr);
+void wvtest_check(bool cond, const char *reason);
+static inline bool wvtest_start_check(const char *file, int line,
+                                     const char *condstr, bool cond)
+{ wvtest_start(file, line, condstr); wvtest_check(cond, NULL); return cond; }
+bool wvtest_start_check_eq(const char *file, int line,
+                          const char *a, const char *b, bool expect_pass);
+bool wvtest_start_check_lt(const char *file, int line,
+                          const char *a, const char *b);
+int wvtest_start_check_frsh(const char *file, int line,
+                           const char *condstr, int frsh_retval);
+
+
+#define WVPASS(cond) \
+    wvtest_start_check(__FILE__, __LINE__, #cond, (cond))
+#define WVPASSEQ(a, b) \
+    wvtest_start_check_eq(__FILE__, __LINE__, (a), (b), true)
+#define WVPASSLT(a, b) \
+    wvtest_start_check_lt(__FILE__, __LINE__, (a), (b))
+#define WVFAIL(cond) \
+    wvtest_start_check(__FILE__, __LINE__, "NOT(" #cond ")", !(cond))
+#define WVFAILEQ(a, b) \
+    wvtest_start_check_eq(__FILE__, __LINE__, (a), (b), false)
+#define WVPASSNE(a, b) WVFAILEQ(a, b)
+#define WVFAILNE(a, b) WVPASSEQ(a, b)
+#define WVFRSH(frshretval) \
+       wvtest_start_check_frsh(__FILE__, __LINE__, #frshretval, (frshretval))
+
+
+#define WVTEST_MAIN3(_descr, ff, ll, _slowness)                                \
+       static void _wvtest_main_##ll();                                \
+       struct WvTest _wvtest_##ll = \
+       { .descr = _descr, .idstr = ff ":" #ll, .main = _wvtest_main_##ll, .slowness = _slowness }, \
+               *_wvtest_ptr_##ll __attribute__ ((section ("wvtest"))) = &_wvtest_##ll; \
+       static void _wvtest_main_##ll()
+#define WVTEST_MAIN2(descr, ff, ll, slowness)  \
+       WVTEST_MAIN3(descr, ff, ll, slowness)
+#define WVTEST_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 0)
+#define WVTEST_SLOW_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 1)
+
+
+#endif // __WVTEST_H
diff --git a/build/aquosa/wvtest/c/wvtestfrsh.c b/build/aquosa/wvtest/c/wvtestfrsh.c
new file mode 100644 (file)
index 0000000..cc1f276
--- /dev/null
@@ -0,0 +1,15 @@
+#include "wvtest.h"
+#include <frsh_error.h>
+
+int wvtest_start_check_frsh(const char *file, int line,
+                            const char *condstr, int frsh_retval)
+{
+       char errstr[80] = "ok";
+       wvtest_start(file, line, condstr);
+       if (frsh_retval != 0)
+               frsh_strerror (frsh_retval, errstr, sizeof(errstr));
+
+       wvtest_check(frsh_retval == 0, errstr);
+
+       return frsh_retval;
+}
diff --git a/build/aquosa/wvtest/c/wvtestmain.c b/build/aquosa/wvtest/c/wvtestmain.c
new file mode 100644 (file)
index 0000000..446e5ba
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#ifdef HAVE_WVCRASH
+# include "wvcrash.h"
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef _WIN32
+#include <io.h>
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+static bool fd_is_valid(int fd)
+{
+#ifdef _WIN32
+    if ((HANDLE)_get_osfhandle(fd) != INVALID_HANDLE_VALUE) return true;
+#endif    
+    int nfd = dup(fd);
+    if (nfd >= 0)
+    {
+       close(nfd);
+       return true;
+    }
+    return false;
+
+}
+
+
+static int fd_count(const char *when)
+{
+    int count = 0;
+    int fd;
+    printf("fds open at %s:", when);
+    
+    for (fd = 0; fd < 1024; fd++)
+    {
+       if (fd_is_valid(fd))
+       {
+           count++;
+           printf(" %d", fd);
+           fflush(stdout);
+       }
+    }
+    printf("\n");
+    
+    return count;
+}
+
+
+int main(int argc, char **argv)
+{
+    char buf[200];
+#if defined(_WIN32) && defined(HAVE_WVCRASH)
+    setup_console_crash();
+#endif
+
+    // test wvtest itself.  Not very thorough, but you have to draw the
+    // line somewhere :)
+    WVPASS(true);
+    WVPASS(1);
+    WVFAIL(false);
+    WVFAIL(0);
+    int startfd, endfd;
+    char * const *prefixes = NULL;
+    
+    if (argc > 1)
+       prefixes = argv + 1;
+    
+    startfd = fd_count("start");
+    int ret = wvtest_run_all(prefixes);
+    
+//    if (ret == 0) // don't pollute the strace output if we failed anyway
+    if (0)
+    {
+       endfd = fd_count("end");
+    
+       WVPASS(startfd == endfd);
+#ifndef _WIN32
+       if (startfd != endfd)
+       {
+           sprintf(buf, "ls -l /proc/%d/fd", getpid());
+           system(buf);
+       }
+#endif    
+    }
+    
+    // keep 'make' from aborting if this environment variable is set
+    if (getenv("WVTEST_NO_FAIL"))
+       return 0;
+    else
+       return ret;
+}
diff --git a/build/aquosa/wvtest/cpp/Makefile b/build/aquosa/wvtest/cpp/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/build/aquosa/wvtest/cpp/Makefile.omk b/build/aquosa/wvtest/cpp/Makefile.omk
new file mode 100644 (file)
index 0000000..8bc2ce4
--- /dev/null
@@ -0,0 +1,7 @@
+
+include_HEADERS = wvtest.h
+
+CFLAGS += -DWVTEST_CONFIGURED
+
+lib_LIBRARIES = wvtest
+wvtest_SOURCES = wvtestmain.cc wvtest.cc
diff --git a/build/aquosa/wvtest/cpp/wvtest.cc b/build/aquosa/wvtest/cpp/wvtest.cc
new file mode 100644 (file)
index 0000000..6ae965d
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#ifdef _WIN32
+#include <direct.h>
+#else
+#include <unistd.h>
+#include <sys/wait.h>
+#endif
+#include <errno.h>
+#include <signal.h>
+#include <frsh_error.h>
+
+#include <cstdlib>
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+# include <valgrind/memcheck.h>
+# include <valgrind/valgrind.h>
+#else
+# define VALGRIND_COUNT_ERRORS 0
+# define VALGRIND_DO_LEAK_CHECK
+# define VALGRIND_COUNT_LEAKS(a,b,c,d) (a=b=c=d=0)
+#endif
+
+#define MAX_TEST_TIME 40     // max seconds for a single test to run
+#define MAX_TOTAL_TIME 120*60 // max seconds for the entire suite to run
+
+#define TEST_START_FORMAT "! %s:%-5d %-40s "
+
+static int memerrs()
+{
+    return (int)VALGRIND_COUNT_ERRORS;
+}
+
+static int memleaks()
+{
+    int leaked = 0, dubious = 0, reachable = 0, suppressed = 0;
+    VALGRIND_DO_LEAK_CHECK;
+    VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
+    printf("memleaks: sure:%d dubious:%d reachable:%d suppress:%d\n",
+          leaked, dubious, reachable, suppressed);
+    fflush(stdout);
+    
+    // dubious+reachable are normally non-zero because of globals...
+    // return leaked+dubious+reachable;
+    return leaked;
+}
+
+// Return 1 if no children are running or zombies, 0 if there are any running
+// or zombie children.
+// Will wait for any already-terminated children first.
+// Passes if no rogue children were running, fails otherwise.
+// If your test gets a failure in here, either you're not killing all your
+// children, or you're not calling waitpid(2) on all of them.
+static bool no_running_children()
+{
+#ifndef _WIN32
+    pid_t wait_result;
+
+    // Acknowledge and complain about any zombie children
+    do 
+    {
+       int status = 0;
+        wait_result = waitpid(-1, &status, WNOHANG);
+
+        if (wait_result > 0)
+        {
+            char buf[256];
+            snprintf(buf, sizeof(buf) - 1, "%d", wait_result);
+            buf[sizeof(buf)-1] = '\0';
+            WVFAILEQ("Unclaimed dead child process", buf);
+        }
+    } while (wait_result > 0);
+        
+    // There should not be any running children, so waitpid should return -1
+    WVPASSEQ(errno, ECHILD);
+    WVPASSEQ(wait_result, -1);
+    return (wait_result == -1 && errno == ECHILD);
+#endif
+    return true;
+}
+
+
+WvTest *WvTest::first, *WvTest::last;
+int WvTest::fails, WvTest::runs;
+time_t WvTest::start_time;
+bool WvTest::run_twice = false;
+
+void WvTest::alarm_handler(int)
+{
+    printf("\n! WvTest  Current test took longer than %d seconds!  FAILED\n",
+          MAX_TEST_TIME);
+    fflush(stdout);
+    abort();
+}
+
+
+static const char *pathstrip(const char *filename)
+{
+    const char *cptr;
+    cptr = strrchr(filename, '/');
+    if (cptr) filename = cptr + 1;
+    cptr = strrchr(filename, '\\');
+    if (cptr) filename = cptr + 1;
+    return filename;
+}
+
+
+WvTest::WvTest(const char *_descr, const char *_idstr, MainFunc *_main,
+              int _slowness) :
+    descr(_descr), 
+    idstr(pathstrip(_idstr)), 
+    main(_main), 
+    slowness(_slowness),
+    next(NULL)
+{
+    if (first)
+       last->next = this;
+    else
+       first = this;
+    last = this;
+}
+
+
+static bool prefix_match(const char *s, const char * const *prefixes)
+{
+    for (const char * const *prefix = prefixes; prefix && *prefix; prefix++)
+    {
+       if (!strncasecmp(s, *prefix, strlen(*prefix)))
+           return true;
+    }
+    return false;
+}
+
+
+int WvTest::run_all(const char * const *prefixes)
+{
+    int old_valgrind_errs = 0, new_valgrind_errs;
+    int old_valgrind_leaks = 0, new_valgrind_leaks;
+    
+#ifdef _WIN32
+    /* I should be doing something to do with SetTimer here, 
+     * not sure exactly what just yet */
+#else
+    char *disable(getenv("WVTEST_DISABLE_TIMEOUT"));
+    if (disable != NULL && disable[0] != '\0' && disable[0] != '0')
+        signal(SIGALRM, SIG_IGN);
+    else
+        signal(SIGALRM, alarm_handler);
+    alarm(MAX_TEST_TIME);
+#endif
+    start_time = time(NULL);
+    
+    // make sure we can always start out in the same directory, so tests have
+    // access to their files.  If a test uses chdir(), we want to be able to
+    // reverse it.
+    char wd[1024];
+    if (!getcwd(wd, sizeof(wd)))
+       strcpy(wd, ".");
+    
+    const char *slowstr1 = getenv("WVTEST_MIN_SLOWNESS");
+    const char *slowstr2 = getenv("WVTEST_MAX_SLOWNESS");
+    int min_slowness = 0, max_slowness = 65535;
+    if (slowstr1) min_slowness = atoi(slowstr1);
+    if (slowstr2) max_slowness = atoi(slowstr2);
+
+#ifdef _WIN32
+    run_twice = false;
+#else
+    char *parallel_str = getenv("WVTEST_PARALLEL");
+    if (parallel_str) 
+        run_twice = atoi(parallel_str) > 0;
+#endif
+
+    // there are lots of fflush() calls in here because stupid win32 doesn't
+    // flush very often by itself.
+    fails = runs = 0;
+    for (WvTest *cur = first; cur; cur = cur->next)
+    {
+       if (cur->slowness <= max_slowness
+           && cur->slowness >= min_slowness
+           && (!prefixes
+               || prefix_match(cur->idstr, prefixes)
+               || prefix_match(cur->descr, prefixes)))
+       {
+#ifndef _WIN32
+            // set SIGPIPE back to default, helps catch tests which don't set
+            // this signal to SIG_IGN (which is almost always what you want)
+            // on startup
+            signal(SIGPIPE, SIG_DFL);
+
+            pid_t child = 0;
+            if (run_twice)
+            {
+                // I see everything twice!
+                printf("Running test in parallel.\n");
+                child = fork();
+            }
+#endif
+
+           printf("\nTesting \"%s\" in %s:\n", cur->descr, cur->idstr);
+           fflush(stdout);
+           
+           cur->main();
+           chdir(wd);
+           
+           new_valgrind_errs = memerrs();
+           WVPASS(new_valgrind_errs == old_valgrind_errs);
+           old_valgrind_errs = new_valgrind_errs;
+           
+           new_valgrind_leaks = memleaks();
+           WVPASS(new_valgrind_leaks == old_valgrind_leaks);
+           old_valgrind_leaks = new_valgrind_leaks;
+           
+           fflush(stderr);
+           printf("\n");
+           fflush(stdout);
+
+#ifndef _WIN32
+            if (run_twice)
+            {
+                if (!child)
+                {
+                    // I see everything once!
+                    printf("Child exiting.\n");
+                    _exit(0);
+                }
+                else
+                {
+                    printf("Waiting for child to exit.\n");
+                    int result;
+                    while ((result = waitpid(child, NULL, 0)) == -1 && 
+                            errno == EINTR)
+                        printf("Waitpid interrupted, retrying.\n");
+                }
+            }
+#endif
+
+            WVPASS(no_running_children());
+       }
+    }
+    
+    WVPASS(runs > 0);
+    
+    if (prefixes && *prefixes && **prefixes)
+       printf("WvTest: WARNING: only ran tests starting with "
+              "specifed prefix(es).\n");
+    else
+       printf("WvTest: ran all tests.\n");
+    printf("WvTest: %d test%s, %d failure%s.\n",
+          runs, runs==1 ? "" : "s",
+          fails, fails==1 ? "": "s");
+    fflush(stdout);
+    
+    return fails != 0;
+}
+
+
+// If we aren't running in parallel, we want to output the name of the test
+// before we run it, so we know what happened if it crashes.  If we are
+// running in parallel, outputting this information in multiple printf()s
+// can confuse parsers, so we want to output everything in one printf().
+//
+// This function gets called by both start() and check().  If we're not
+// running in parallel, just print the data.  If we're running in parallel,
+// and we're starting a test, save a copy of the file/line/description until
+// the test is done and we can output it all at once.
+//
+// Yes, this is probably the worst API of all time.
+void WvTest::print_result(bool start, const char *_file, int _line, 
+                         const char *_condstr, const char *result)
+{
+    static char *file;
+    static char *condstr;
+    static int line;
+    
+    if (start)
+    {
+        if (file) 
+            free(file);
+        if (condstr) 
+            free(condstr);
+        file = strdup(pathstrip(_file));
+        condstr = strdup(_condstr);
+        line = _line;
+
+        for (char *cptr = condstr; *cptr; cptr++)
+        {
+            if (!isprint((unsigned char)*cptr))
+                *cptr = '!';
+        }
+    }
+            
+    if (run_twice)
+    {
+        if (!start)
+            printf(TEST_START_FORMAT "%s\n", file, line, condstr, result);
+    }
+    else
+    {
+        if (start)
+            printf(TEST_START_FORMAT, file, line, condstr);
+        else
+            printf("%s\n", result);
+    }
+    fflush(stdout);
+
+    if (!start)
+    {
+        if (file)
+            free(file);
+        if (condstr)
+            free(condstr);
+        file = condstr = NULL;
+    }
+}
+
+
+void WvTest::start(const char *file, int line, const char *condstr)
+{
+    // Either print the file, line, and condstr, or save them for later.
+    print_result(true, file, line, condstr, false);
+}
+
+
+void WvTest::check(bool cond, const char *reason)
+{
+#ifndef _WIN32
+    alarm(MAX_TEST_TIME); // restart per-test timeout
+#endif
+    if (!start_time) start_time = time(NULL);
+    
+    if (time(NULL) - start_time > MAX_TOTAL_TIME)
+    {
+       printf("\n! WvTest   Total run time exceeded %d seconds!  FAILED\n",
+              MAX_TOTAL_TIME);
+       fflush(stdout);
+       abort();
+    }
+    
+    runs++;
+
+    print_result(false, NULL, 0, NULL, cond ? "ok" : reason);
+
+    if (!cond)
+    {
+       fails++;
+       
+       if (getenv("WVTEST_DIE_FAST"))
+           abort();
+    }
+}
+
+
+bool WvTest::start_check_eq(const char *file, int line,
+                           const char *a, const char *b, bool expect_pass)
+{
+    if (!a) a = "";
+    if (!b) b = "";
+    
+    size_t len = strlen(a) + strlen(b) + 8 + 1;
+    char *str = new char[len];
+    sprintf(str, "[%s] %s [%s]", a, expect_pass ? "==" : "!=", b);
+    
+    start(file, line, str);
+    delete[] str;
+    
+    bool cond = !strcmp(a, b);
+    if (!expect_pass)
+        cond = !cond;
+
+    check(cond);
+    return cond;
+}
+
+
+bool WvTest::start_check_eq(const char *file, int line,
+                           const std::string &a, const std::string &b, 
+                            bool expect_pass)
+{
+    return start_check_eq(file, line, a.c_str(), b.c_str(), expect_pass);
+}
+
+
+bool WvTest::start_check_eq(const char *file, int line, 
+                            int a, int b, bool expect_pass)
+{
+    size_t len = 128 + 128 + 8 + 1;
+    char *str = new char[len];
+    sprintf(str, "%d %s %d", a, expect_pass ? "==" : "!=", b);
+    
+    start(file, line, str);
+    delete[] str;
+    
+    bool cond = (a == b);
+    if (!expect_pass)
+        cond = !cond;
+
+    check(cond);
+    return cond;
+}
+
+
+bool WvTest::start_check_lt(const char *file, int line,
+                           const char *a, const char *b)
+{
+    if (!a) a = "";
+    if (!b) b = "";
+    
+    size_t len = strlen(a) + strlen(b) + 8 + 1;
+    char *str = new char[len];
+    sprintf(str, "[%s] < [%s]", a, b);
+    
+    start(file, line, str);
+    delete[] str;
+
+    bool cond = strcmp(a, b) < 0;
+    check(cond);
+    return cond;
+}
+
+
+bool WvTest::start_check_lt(const char *file, int line, int a, int b)
+{
+    size_t len = 128 + 128 + 8 + 1;
+    char *str = new char[len];
+    sprintf(str, "%d < %d", a, b);
+    
+    start(file, line, str);
+    delete[] str;
+    
+    bool cond = a < b;
+    check(cond);
+    return cond;
+}
+
+int WvTest::start_check_frsh(const char *file, int line,
+                            const char *condstr, int frsh_retval)
+{
+       char errstr[80] = "ok";
+       start(file, line, condstr);
+       if (frsh_retval != 0)
+               frsh_strerror (frsh_retval, errstr, sizeof(errstr));
+
+       check(frsh_retval == 0, errstr);
+
+       return frsh_retval;
+}
diff --git a/build/aquosa/wvtest/cpp/wvtest.h b/build/aquosa/wvtest/cpp/wvtest.h
new file mode 100644 (file)
index 0000000..287e3fb
--- /dev/null
@@ -0,0 +1,88 @@
+/* -*- Mode: C++ -*-
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */ 
+#ifndef __WVTEST_H
+#define __WVTEST_H
+
+#ifndef WVTEST_CONFIGURED
+# error "Missing settings: HAVE_VALGRIND_MEMCHECK_H HAVE_WVCRASH WVTEST_CONFIGURED"
+#endif
+
+#include <time.h>
+#include <string>
+
+class WvTest
+{
+    typedef void MainFunc();
+    const char *descr, *idstr;
+    MainFunc *main;
+    int slowness;
+    WvTest *next;
+    static WvTest *first, *last;
+    static int fails, runs;
+    static time_t start_time;
+    static bool run_twice;
+    
+    static void alarm_handler(int sig);
+   
+    static void
+    print_result(bool start, const char *file, int line, 
+                const char *condstr, const char *result);
+
+    static inline void
+    print_result(bool start, const char *file, int line, 
+                const char *condstr, bool result)
+       { print_result(start, file, line, condstr, result ? "ok" : "FAILED"); }
+public:
+    WvTest(const char *_descr, const char *_idstr, MainFunc *_main, int _slow);
+    static int run_all(const char * const *prefixes = NULL);
+    static void start(const char *file, int line, const char *condstr);
+    static void check(bool cond, const char *reason = "FAILED");
+    static inline bool start_check(const char *file, int line,
+                                  const char *condstr, bool cond)
+        { start(file, line, condstr); check(cond); return cond; }
+    static bool start_check_eq(const char *file, int line,
+                              const char *a, const char *b, bool expect_pass);
+    static bool start_check_eq(const char *file, int line,
+                              const std::string &a, const std::string &b, 
+                               bool expect_pass);
+    static bool start_check_eq(const char *file, int line, int a, int b,
+                               bool expect_pass);
+    static bool start_check_lt(const char *file, int line,
+                               const char *a, const char *b);
+    static bool start_check_lt(const char *file, int line, int a, int b);
+    static int start_check_frsh(const char *file, int line,
+                               const char *condstr, int frsh_retval);
+};
+
+
+#define WVPASS(cond) \
+    WvTest::start_check(__FILE__, __LINE__, #cond, (cond))
+#define WVPASSEQ(a, b) \
+    WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), true)
+#define WVPASSLT(a, b) \
+    WvTest::start_check_lt(__FILE__, __LINE__, (a), (b))
+#define WVFAIL(cond) \
+    WvTest::start_check(__FILE__, __LINE__, "NOT(" #cond ")", !(cond))
+#define WVFAILEQ(a, b) \
+    WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), false)
+#define WVPASSNE(a, b) WVFAILEQ(a, b)
+#define WVFAILNE(a, b) WVPASSEQ(a, b)
+#define WVFRSH(frshretval) \
+       WvTest::start_check_frsh(__FILE__, __LINE__, #frshretval, (frshretval))
+
+
+#define WVTEST_MAIN3(descr, ff, ll, slowness) \
+    static void _wvtest_main_##ll(); \
+    static WvTest _wvtest_##ll(descr, ff, _wvtest_main_##ll, slowness); \
+    static void _wvtest_main_##ll()
+#define WVTEST_MAIN2(descr, ff, ll, slowness) \
+    WVTEST_MAIN3(descr, ff, ll, slowness)
+#define WVTEST_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 0)
+#define WVTEST_SLOW_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 1)
+
+
+#endif // __WVTEST_H
diff --git a/build/aquosa/wvtest/cpp/wvtestmain.cc b/build/aquosa/wvtest/cpp/wvtestmain.cc
new file mode 100644 (file)
index 0000000..b44dfb5
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * WvTest:
+ *   Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ *       Licensed under the GNU Library General Public License, version 2.
+ *       See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#ifdef HAVE_WVCRASH
+# include "wvcrash.h"
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef _WIN32
+#include <io.h>
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+static bool fd_is_valid(int fd)
+{
+#ifdef _WIN32
+    if ((HANDLE)_get_osfhandle(fd) != INVALID_HANDLE_VALUE) return true;
+#endif    
+    int nfd = dup(fd);
+    if (nfd >= 0)
+    {
+       close(nfd);
+       return true;
+    }
+    return false;
+
+}
+
+
+static int fd_count(const char *when)
+{
+    int count = 0;
+    
+    printf("fds open at %s:", when);
+    
+    for (int fd = 0; fd < 1024; fd++)
+    {
+       if (fd_is_valid(fd))
+       {
+           count++;
+           printf(" %d", fd);
+           fflush(stdout);
+       }
+    }
+    printf("\n");
+    
+    return count;
+}
+
+
+int main(int argc, char **argv)
+{
+    char buf[200];
+#if defined(_WIN32) && defined(HAVE_WVCRASH)
+    setup_console_crash();
+#endif
+
+    // test wvtest itself.  Not very thorough, but you have to draw the
+    // line somewhere :)
+    WVPASS(true);
+    WVPASS(1);
+    WVFAIL(false);
+    WVFAIL(0);
+    int startfd, endfd;
+    char * const *prefixes = NULL;
+    
+    if (argc > 1)
+       prefixes = argv + 1;
+    
+    startfd = fd_count("start");
+    int ret = WvTest::run_all(prefixes);
+    
+    if (ret == 0) // don't pollute the strace output if we failed anyway
+    {
+       endfd = fd_count("end");
+    
+       WVPASS(startfd == endfd);
+#ifndef _WIN32
+       if (startfd != endfd)
+       {
+           sprintf(buf, "ls -l /proc/%d/fd", getpid());
+           system(buf);
+       }
+#endif    
+    }
+    
+    // keep 'make' from aborting if this environment variable is set
+    if (getenv("WVTEST_NO_FAIL"))
+       return 0;
+    else
+       return ret;
+}
diff --git a/build/aquosa/wvtestrun b/build/aquosa/wvtestrun
new file mode 120000 (symlink)
index 0000000..eebe3b7
--- /dev/null
@@ -0,0 +1 @@
+../../src/wvtest/wvtestrun
\ No newline at end of file
diff --git a/build/marte/Makefile b/build/marte/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/build/marte/Makefile.omk b/build/marte/Makefile.omk
new file mode 100644 (file)
index 0000000..c459c78
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS=$(ALL_OMK_SUBDIRS)
diff --git a/build/marte/Makefile.rules b/build/marte/Makefile.rules
new file mode 100644 (file)
index 0000000..b020a32
--- /dev/null
@@ -0,0 +1,1356 @@
+#                   Version for Linux/RTLinux builds.        #OMK@linux
+#
+#  Makefile.rules - OCERA make framework common project rules -*- makefile -*- #OMK@base
+#
+#  (C) Copyright 2003 by Pavel Pisa - OCERA team member
+#  (C) Copyright 2006 by Michal Sojka - Czech Technical University, FEE, DCE
+#
+#  Homepage: http://rtime.felk.cvut.cz/omk/
+#
+# The OMK build system is distributed under the GNU General Public
+# License.  See file COPYING for details.
+#
+# input variables
+# V                .. if set to 1, full command text is shown else short form is used
+# W                .. whole tree - if set to 1, make is always called from the top-level directory
+# SUBDIRS          .. list of subdirectories intended for make from actual directory
+# default_CONFIG   .. list of default config assignments CONFIG_XXX=y/n ...
+# LN_HEADERS       .. if "y", header files are symbolicaly linked instead of copied. #OMK@include
+#                                                            #OMK@linux
+# input variables
+# lib_LIBRARIES    .. list of the user-space libraries
+# shared_LIBRARIES .. list of the user-space shared libraries
+# kernel_LIBRARIES .. list of the kernel-space libraries
+# rtlinux_LIBRARIES.. list of the RT-Linux kernel-space libraries
+# include_HEADERS  .. list of the user-space public header files
+# nobase_include_HEADERS .. public headers copied even with directory part
+# renamed_include_HEADERS .. public headers copied to the different target name
+# kernel_HEADERS   .. list of the kernel-space public header files
+# rtlinux_HEADERS  .. list of the RT-Linux kernel-space public header files
+# bin_PROGRAMS     .. list of the require binary programs
+# utils_PROGRAMS   .. list of the development utility programs
+# test_PROGRAMS    .. list of the testing programs
+# kernel_MODULES   .. list of the kernel side modules/applications
+# rtlinux_MODULES  .. list of RT-Linux the kernel side modules/applications
+# xxx_SOURCES      .. list of specific target sources
+# xxx_LIBS         .. list of specific target libraries
+# INCLUDES         .. additional include directories and defines for user-space
+# kernel_INCLUDES  .. additional include directories and defines for kernel-space
+# rtlinux_INCLUDES .. additional include directories and defines for RT-Linux
+# OMIT_KERNEL_PASSES  if defined, all kernel passes are omited
+#
+# LINUX_DIR        .. location of Linux kernel sources
+# RTL_DIR          .. location of RT-Linux sources
+# CFLAGS           .. C compiler flags
+# CXXFLAGS         .. C++ compiler flags
+# CPPFLAGS        .. C preprocessor flags
+# LDFLAGS         .. linker flags for programs linking
+# LOCAL_CONFIG_H   .. name of local config.h file generated from values #OMK@config_h
+#                     of options defined in the current directory
+# config_include_HEADERS .. names of global config files (possibly
+#                     with subdirectories)
+# xxx_DEFINES      .. list of config directives to be included in
+#                     config header file of the name <somedir>/xxx.h
+# DOXYGEN          .. if non-empty, generated headers includes Doxygen's @file
+#                    command, so it is possible to document config
+#                    variables.
+# QT_SUBDIRS       .. subdirectories where to build QT applications using qmake #OMK@qt
+# QTDIR                   .. where QT resides
+OMK_RULES_TYPE=linux                                         #OMK@__type
+                                                             #OMK@base
+# We need to ensure definition of sources directory first
+ifndef SOURCES_DIR
+# Only shell built-in pwd understands -L
+SOURCES_DIR := $(shell ( pwd -L ) )
+endif
+
+# If we are not called by OMK leaf Makefile...
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(abspath $(dir $(filter %Makefile.rules,$(MAKEFILE_LIST))))
+endif
+
+# OUTPUT_DIR is the place where _compiled, _build and possible other
+# files/directories are created. By default is the same as
+# $(MAKERULES_DIR).
+ifndef OUTPUT_DIR
+OUTPUT_DIR := $(MAKERULES_DIR)
+endif
+
+.PHONY: all default check-make-ver omkize
+
+ifdef W
+  ifeq ("$(origin W)", "command line")
+    OMK_WHOLE_TREE:=$(W)
+  endif
+endif
+ifndef OMK_WHOLE_TREE
+  OMK_WHOLE_TREE:=0
+endif
+
+ifneq ($(OMK_WHOLE_TREE),1)
+all: check-make-ver default
+       @echo "Compilation finished"
+else
+# Run make in the top-level directory
+all:
+       @$(MAKE) -C $(MAKERULES_DIR) OMK_SERIALIZE_INCLUDED=n SOURCES_DIR=$(MAKERULES_DIR) RELATIVE_DIR="" $(MAKECMDGOALS) W=0
+endif
+
+ifdef OMK_TESTSROOT
+# Usage: $(call canttest,<error message>)
+define canttest
+       ( echo "$(1)" > $(OUTPUT_DIR)/_canttest; echo "$(1)"; exit 1 )
+endef
+else
+define canttest
+       echo "$(1)"
+endef
+endif
+
+#=========================
+# Include the config file
+
+# FIXME: I think CONFIG_FILE_OK variable is useless. We have three
+# config files and it is not clearly defined to which file is this
+# variable related.
+ifneq ($(CONFIG_FILE_OK),y)
+ifndef CONFIG_FILE
+CONFIG_FILE      := $(OUTPUT_DIR)/config.omk
+endif
+ifneq ($(wildcard $(CONFIG_FILE)-default),)
+-include $(CONFIG_FILE)-default
+else
+ifneq ($(MAKECMDGOALS),default-config)
+$(warning Please, run "make default-config" first)
+endif
+endif
+
+-include $(OUTPUT_DIR)/config.target
+
+ifneq ($(wildcard $(CONFIG_FILE)),)
+-include $(CONFIG_FILE)
+CONFIG_FILE_OK = y
+endif
+endif #$(CONFIG_FILE_OK)
+
+
+CONFIG_FILES ?= $(wildcard $(CONFIG_FILE)-default) $(wildcard $(OUTPUT_DIR)/config.target) $(wildcard $(CONFIG_FILE))
+
+
+export SOURCES_DIR MAKERULES_DIR RELATIVE_DIR
+export CONFIG_FILE CONFIG_FILES OMK_SERIALIZE_INCLUDED OMK_VERBOSE OMK_SILENT
+# OMK_SERIALIZE_INCLUDED has to be exported to submakes because passes
+# must to be serialized only in the toplevel make.
+
+ifndef RELATIVE_DIR
+RELATIVE_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+endif
+#$(warning  === RELATIVE_DIR = "$(RELATIVE_DIR)" ===)
+override RELATIVE_DIR := $(RELATIVE_DIR:/%=%)
+override RELATIVE_DIR := $(RELATIVE_DIR:\\%=%)
+#$(warning  RELATIVE_DIR = "$(RELATIVE_DIR)")
+override BACK2TOP_DIR := $(shell echo $(RELATIVE_DIR)/ | sed -e 's_//_/_g' -e 's_/\./_/_g' -e 's_^\./__g'  -e 's_\([^/][^/]*\)_.._g' -e 's_/$$__')
+#$(warning  BACK2TOP_DIR = "$(BACK2TOP_DIR)")
+
+#$(warning SOURCES_DIR = "$(SOURCES_DIR)")
+#$(warning MAKERULES_DIR = "$(OUTPUT_DIR)")
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+
+# We have to use RELATIVE_PREFIX because of mingw
+override RELATIVE_PREFIX := $(RELATIVE_DIR)/
+override RELATIVE_PREFIX := $(RELATIVE_PREFIX:/%=%)
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+# Define srcdir for Automake compatibility
+srcdir = $(SOURCES_DIR)
+
+# Defines for quiet compilation
+ifdef V
+  ifeq ("$(origin V)", "command line")
+    OMK_VERBOSE = $(V)
+  endif
+endif
+ifndef OMK_VERBOSE
+  OMK_VERBOSE = 0
+endif
+ifneq ($(OMK_VERBOSE),0)
+  Q =
+else
+  Q = @
+endif
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+  QUIET_CMD_ECHO = true
+  OMK_SILENT = 1
+else
+  QUIET_CMD_ECHO = echo
+endif
+
+MAKEFILE_OMK=Makefile.omk
+# All subdirectories (even linked ones) containing Makefile.omk
+# Usage in Makefile.omk: SUBDIRS = $(ALL_OMK_SUBDIRS)
+ALL_OMK_SUBDIRS = $(patsubst %/$(MAKEFILE_OMK),%,$(patsubst $(SOURCES_DIR)/%,%,$(wildcard $(SOURCES_DIR)/*/$(MAKEFILE_OMK))))
+
+# ===================================================================
+# We have set up all important variables, so we can check and include
+# real OCERA style Makefile.omk now
+ifndef OMK_INCLUDED
+include $(SOURCES_DIR)/$(MAKEFILE_OMK)
+ifeq ($(AUTOMATIC_SUBDIRS),y)
+SUBDIRS?=$(ALL_OMK_SUBDIRS)
+endif
+OMK_INCLUDED := 1
+endif
+
+check-make-ver:
+       @GOOD_MAKE_VERSION=`echo $(MAKE_VERSION) | sed -n -e 's/^[4-9]\..*\|^3\.9[0-9].*\|^3\.8[1-9].*/y/p'` ; \
+       if [ x$$GOOD_MAKE_VERSION != xy ] ; then \
+               echo "Your make program version is too old and does not support OMK system." ; \
+               echo "Please update to make program 3.81beta1 or newer." ; exit 1 ; \
+       fi
+
+distclean dist-clean:
+       @$(QUIET_CMD_ECHO) "  RM      $(COMPILED_DIR_NAME) $(BUILD_DIR_NAME)"
+       @rm -fr $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)  $(OUTPUT_DIR)/$(BUILD_DIR_NAME)
+
+# Common OMK templates
+# ====================
+
+# Syntax: $(call mkdir,<dir name>)
+define mkdir_def
+       [ -d $(1) ] || mkdir -p $(1) || exit 1
+endef
+
+ifneq ($(OMK_VERBOSE),2)
+NO_PRINT_DIRECTORY := --no-print-directory
+endif
+
+ifeq ($(USE_LEAF_MAKEFILES),n)
+export USE_LEAF_MAKEFILES
+SUBDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+SOURCESDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+else
+SUBDIR_MAKEFILE=$(SOURCES_DIR)/$(3)/Makefile
+SOURCESDIR_MAKEFILE=$(SOURCES_DIR)/Makefile
+endif
+
+pass = $(strip $(1))
+
+# Call a pass in a subdirectory
+# Usage: $(call omk_pass_subdir_template,<pass name>,<build dir>,<subdir>)
+define omk_pass_subdir_template
+.PHONY: $(pass)-$(3)-subdir
+$(pass)-submakes: $(pass)-$(3)-subdir
+$(pass)-$(3)-subdir:
+       @$(call mkdir_def,$(2)/$(3))
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(3) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(3) -C $(2)/$(3) \
+               -f $(SUBDIR_MAKEFILE) $(pass)-submakes
+# In subdirectories we can call submakes directly since passes are
+# already searialized on the toplevel make.
+endef
+
+ifdef OMK_TESTSROOT
+check-target = $(1:%=%-check)
+endif
+
+# Call a pass in a subdirectory
+# Usage: $(call extra_rules_subdir_template,<subdir>)
+define extra_rules_subdir_template
+extra-rules-subdirs: extra-rules-$(1)
+extra-rules-$(1):
+       +@$(MAKE) OMK_SERIALIZE_INCLUDED=n MAKERULES_DIR=$(SOURCES_DIR)/$(1) OUTPUT_DIR=$(OUTPUT_DIR) \
+               SOURCES_DIR=$(SOURCES_DIR)/$(1) RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) -C $(SOURCES_DIR)/$(1)
+endef
+
+.PHONY: extra-rules-subdirs
+extra-rules-subdirs:
+
+$(foreach subdir,$(EXTRA_RULES_SUBDIRS),$(eval $(call extra_rules_subdir_template,$(subdir))))
+
+# Usage: $(call omk_pass_template,<pass name>,<build dir>,[<local make flags>],[<local enable condition>])
+define omk_pass_template
+.PHONY: $(pass) $(pass)-local $(pass)-check $(pass)-submakes
+$(foreach subdir,$(SUBDIRS),$(eval $(call omk_pass_subdir_template,$(pass),$(2),$(subdir))))
+$(pass):
+# Submakes have to be called this way and not as dependecies for pass
+# serialization to work
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_DIR) \
+               -f $(SOURCESDIR_MAKEFILE) $(pass)-submakes
+$(pass)-submakes:
+       @true                   # Do not emit "nothing to be done" messages
+
+ifneq ($(4)$($(pass)_HOOKS),)
+$(pass)-submakes: $(pass)-this-dir
+$(pass)-this-dir: $(foreach subdir,$(SUBDIRS),$(pass)-$(subdir)-subdir)
+       +@echo "make[omk]: $(pass) in $(RELATIVE_DIR)"
+       @$(call mkdir_def,$(2))
+       +@$(MAKE) $(NO_PRINT_DIRECTORY) SOURCES_DIR=$(SOURCES_DIR) RELATIVE_DIR=$(RELATIVE_DIR) -C $(2) \
+               -f $(SOURCESDIR_MAKEFILE) $(3) $(check-target) $(1:%=%-local)
+$(pass)-local: $($(pass)_HOOKS)
+endif
+endef
+
+# =======================
+# DEFAULT CONFIG PASS
+
+default-config:
+       @echo "# Start of OMK config file" > "$(CONFIG_FILE)-default"
+       @echo "# This file should not be altered manually" >> "$(CONFIG_FILE)-default"
+       @echo "# Overrides should be stored in file $(notdir $(CONFIG_FILE))" >> "$(CONFIG_FILE)-default"
+       @echo >> "$(CONFIG_FILE)-default"
+       @$(MAKE) $(NO_PRINT_DIRECTORY) -C $(OUTPUT_DIR) \
+               RELATIVE_DIR="" SOURCES_DIR=$(OUTPUT_DIR) \
+               -f $(OUTPUT_DIR)/Makefile default-config-pass
+
+$(eval $(call omk_pass_template,default-config-pass,$$(LOCAL_BUILD_DIR),,always))
+
+default-config-pass-local:
+#      @echo Default config for $(RELATIVE_DIR)
+       @echo "# Config for $(RELATIVE_DIR)" >> "$(CONFIG_FILE)-default"
+       @$(foreach x, $(default_CONFIG), echo '$(x)' | \
+               sed -e 's/^[^=]*=x$$/#\0/' >> "$(CONFIG_FILE)-default" ; )
+
+
+omkize:
+       $(Q)if ! grep -q MAKERULES_DIR Makefile; then \
+          echo "Makefile is not OMK leaf makefile!" >&2; exit 1; \
+       fi
+       $(Q)for i in `find -L . -name Makefile.omk` ; do \
+          d=`dirname $${i}`; \
+          if ! test -f "$${d}/Makefile.rules" && ( ! test -f "$${d}/Makefile" || ! cmp --silent Makefile "$${d}/Makefile" ); then \
+             rm -f "$${d}/Makefile"; \
+             cp -v Makefile "$${d}/Makefile"; \
+          fi \
+       done
+ifeq ($(OMK_VERBOSE),1)                                      #OMK@include
+CPHEADER_FLAGS += -v
+LNHEADER_FLAGS += -v
+endif
+
+ifneq ($(LN_HEADERS),y)
+define cp_cmd
+( echo "  CP      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; cp $(CPHEADER_FLAGS) $(1) $(2) )
+endef
+else
+define cp_cmd
+( echo "  LN      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; [ -f $(1) ] && ln -sf $(LNHEADER_FLAGS) $(1) $(2) )
+endef
+endif
+
+# TODO: Check modification date of changed header files. If it is
+# newer that in source dir, show a warning.
+
+# Syntax: $(call include-pass-template,<include dir>,<keyword>)
+define include-pass-template
+include-pass-local: include-pass-local-$(2)
+include-pass-local-$(2): $$($(2)_GEN_HEADERS) $$(foreach f,$$(renamed_$(2)_GEN_HEADERS),$$(shell echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'))
+       @$$(foreach f, $$($(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(notdir $$(f)) \
+          || $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; )
+       @$$(foreach f, $$($(2)_GEN_HEADERS), cmp --quiet $$(f) $(1)/$$(notdir $$(f)) \
+          || $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; ) # FIXME: Use correct build dir, then document it
+       @$$(foreach f, $$(nobase_$(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(f) \
+          || ( mkdir -p $(1)/$$(dir $$(f)) && $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(f)) ) || exit 1 ; )
+       @$$(foreach f, $$(renamed_$(2)_HEADERS), \
+          srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+          cmp --quiet $$(SOURCES_DIR)/$$$${srcfname} $(1)/$$$${destfname} \
+          || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(SOURCES_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+       @$$(foreach f, $$(renamed_$(2)_GEN_HEADERS), \
+          srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+          cmp --quiet $$$${srcfname} $(1)/$$$${destfname} \
+          || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+endef
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@linux
+# Hack to check RT-Linux rules
+#LINUX_DIR := /home/cvs/ocera/ocera-build/kernel/linux
+#RTL_DIR := /home/cvs/ocera/ocera-build/kernel/rtlinux
+#CONFIG_RTLINUX = y
+#OCERA_DIR := $(shell ( cd -L $(OUTPUT_DIR)/../../.. ; pwd -L ) )
+
+-include $(OUTPUT_DIR)/OCERA_TOP_DIR
+
+BUILD_DIR_NAME = _build
+COMPILED_DIR_NAME = _compiled
+ifndef GROUP_DIR_NAME
+GROUP_DIR_NAME = nogroup
+endif
+
+ifdef OCERA_DIR
+ifeq ($(wildcard $(OCERA_DIR)/ocera.mk),)
+$(warning "ocera.mk" file does not exist. Adapt Makefile.rules for standalone compilation)
+$(warning (comment out definition of OCERA_DIR line and optionally select RTL_DIR) )
+$(error or go to the ocera/ directory and do 'make' to generate the "ocera.mk" file first, please)
+endif
+include $(OCERA_DIR)/ocera.mk
+KERN_INCLUDE_DIR := $(OCERA_KERNEL_INCLUDES_DIR)
+KERN_LIB_DIR     := $(OCERA_KERNEL_LIBRARIES_DIR)
+KERN_MODULES_DIR := $(OCERA_MODULES_DIR)
+KERN_BUILD_DIR   := $(BUILD_DIR)/kern/$(GROUP_DIR_NAME)
+KERN_MODPOST_DIR := $(BUILD_DIR)/kern-modpost
+USER_INCLUDE_DIR := $(OCERA_USER_INCLUDES_DIR)
+USER_LIB_DIR     := $(OCERA_USER_LIBRARIES_DIR)
+USER_UTILS_DIR   := $(TARGET_DIR)/usr/bin
+USER_TESTS_DIR   := $(TARGET_DIR)/usr/bin
+USER_BIN_DIR     := $(TARGET_DIR)/usr/bin
+USER_BUILD_DIR   := $(BUILD_DIR)/user/$(GROUP_DIR_NAME)
+#LINUX_DIR        := $(OCERA_DIR)/kernel/linux
+#RTL_DIR          := $(OCERA_DIR)/kernel/rtlinux
+#CONFIG_FILE      := $(OCERA_DIR)/emdebsys/.config 
+ifneq ($(wildcard $(CONFIG_FILE)),)
+CONFIG_FILE_OK = y
+endif
+else # OCERA_DIR
+KERN_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include-kern
+KERN_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib-kern
+KERN_MODULES_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/modules
+KERN_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern
+KERN_MODPOST_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern-modpost
+USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include
+USER_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib
+USER_UTILS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils
+USER_TESTS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests
+USER_BIN_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin
+USER_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user
+
+ifndef LINUX_VERSION
+LINUX_VERSION=$(shell uname -r)
+endif
+ifndef LINUX_DIR
+LINUX_DIR=/lib/modules/$(LINUX_VERSION)/build
+endif
+endif # OCERA_DIR
+
+ifeq ($(BUILD_OS),)
+  # Check for target
+  ifeq ($(OS),Windows_NT)
+    BUILD_OS := win32
+  else
+    BUILD_OS := $(shell uname | tr '[A-Z]' '[a-z]' )
+    #$(warning BUILD_OS=$(BUILD_OS))
+  endif
+endif
+
+ifeq ($(TARGET_OS),)
+  TARGET_OS := $(BUILD_OS)
+endif
+
+export TARGET_OS
+export BUILD_OS
+
+LOCAL_BUILD_DIR  = $(USER_OBJS_DIR)
+
+# Assign default values to CFLAGS variable. If the variable is defined
+# earlier (i.g. in config.omk), it is not overriden here.
+CFLAGS ?= -O2 -Wall
+CXXFLAGS ?= -O2 -Wall
+
+
+CPPFLAGS  += -I $(USER_INCLUDE_DIR)
+
+LOADLIBES += -L$(USER_LIB_DIR) 
+
+LOADLIBES += $(lib_LOADLIBES:%=-l%)
+
+LIB_CPPFLAGS += $(CPPFLAGS)
+LIB_CFLAGS   += $(CFLAGS)
+
+ifeq ($(TARGET_OS),win32)
+  SOLIB_EXT = dll
+else
+  SOLIB_EXT = so
+  SOLIB_PICFLAGS += -fpic
+endif
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR)
+KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR)
+
+.PHONY: dep subdirs clean clean-custom cleandepend check-dir
+
+# Some support to serialize some targets for parallel make
+ifneq ($(OMK_SERIALIZE_INCLUDED),y)
+include-pass: check-dir
+library-pass: include-pass
+binary-pass: library-pass
+kernel-lib-pass: include-pass
+kernel-mod-pass: kernel-lib-pass
+kernel-modpost-pass: kernel-mod-pass
+kernel-pass: kernel-mod-pass kernel-modpost-pass
+
+override OMK_SERIALIZE_INCLUDED = y
+MAKEOVERRIDES := $(filter-out OMK_SERIALIZE_INCLUDED=n,$(MAKEOVERRIDES))
+endif
+
+# Checks for OMK tester
+ifdef OMK_TESTSROOT
+default-config-pass-check include-pass-check:
+library-pass-check binary-pass-check:
+       @[ -x "$(shell which $(CC))" ] || $(call canttest,Cannot find compiler: $(CC))
+endif
+
+#=====================================================================
+# User-space rules and templates to compile programs, libraries etc.
+
+ifdef USER_RULE_TEMPLATES
+
+USER_SOURCES2OBJS = .o/.c .o/.cc .o/.cxx .o/.S .o/.o
+
+USER_SOURCES2OBJSLO = .lo/.c .lo/.cc .lo/.cxx .lo/.S .lo/.lo
+
+#%.lo: %.c
+#      $(CC) -o $@ $(LCFLAGS) -c $<
+
+c_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+cc_o_COMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+S_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASFLAGS) -DOMK_FOR_USER
+
+idl_COMPILE = $(IDL_COMPILER)
+
+# Check GCC version for user build
+ifndef CC_MAJOR_VERSION
+CC_MAJOR_VERSION := $(shell $(CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(CC_MAJOR_VERSION),2)
+CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+
+# Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_c_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CC      $$@"
+       $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_cc_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CXX     $$@"
+       $(Q) if $$(cc_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_S_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  AS      $$@"
+       $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call CMETRIC_o_h_template,<object_file>,<target_header>)
+define CMETRIC_o_h_template
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CMETRIC $$@"
+       $(Q)if [ -n `dirname $$@` ] ; then \
+             if [ ! -e `dirname $$@` ] ; then \
+               mkdir -p `dirname $$@` ; fi ; fi
+       $(Q)echo >$$@ '/* Automatically generated from $$< */'
+       $(Q)echo >>$$@ '/* Conditionals to control compilation */'
+       $(Q)set -o pipefail ; $(NM) $$< \
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2cond_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@
+       $(Q)echo >>$$@ '/* Defines from the values defined to symbols */'
+       $(Q)set -o pipefail ; $(NM) $$< \
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2def_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@
+endef
+
+
+
+define COMPILE_idl_template
+$(2).c $(2)-stubs.c $(2)-skels.c $(2)-common.c $(2).h: $(1)
+       @$(QUIET_CMD_ECHO) "  IDL     $$@"
+       $(Q) $$(idl_COMPILE) $$($(2)_IDLFLAGS) $(1)
+endef
+
+
+# Syntax: $(call PROGRAM_template,<dir>,<executable-name>,<executable-suffix>,<linker-sript>)
+# FIXME: ???????? asi je tu blbej komentar
+define PROGRAM_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(2)/$(1)$(3): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q) $$(if $$(filter %.cc,$$($(1)_SOURCES:%.cxx=%.cc)),$$(CXX),$$(CC)) \
+         $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(LDFLAGS) -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$@
+       @echo "$(2)/$(1)$(3): \\" >$(USER_OBJS_DIR)/$(1).exe.d
+       @sed -n -e 's|^LOAD \(.*\)$$$$|  \1  \&|p' $(USER_OBJS_DIR)/$(1).exe.map|tr '&' '\134'  >>$(USER_OBJS_DIR)/$(1).exe.d
+       @echo >>$(USER_OBJS_DIR)/$(1).exe.d
+endef
+
+
+# Syntax: $(call LIBRARY_template,<library-name>)
+define LIBRARY_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR      $$@"
+       $(Q) $(AR) rcs $$@ $$^
+endef
+
+
+# Syntax: $(call SOLIB_template,<library-name>)
+define SOLIB_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+SOLIB_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJSLO),
+$(1)_OBJSLO += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJSLO := $$(sort $$($(1)_OBJSLO:%/=%))
+
+SOLIB_OBJS  += $$($(1)_OBJSLO)
+SOLIB_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).$(SOLIB_EXT): $$($(1)_OBJSLO)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q) $(CC) --shared -Xlinker -soname=lib$(1).$(SOLIB_EXT) -o $$@ $$^ $$(LOADLIBES) $$($(1)_LIBS:%=-l%)
+endef
+
+
+
+library-pass-local: $(addprefix $(USER_INCLUDE_DIR)/,$(cmetric_include_HEADERS)) \
+                   $(lib_LIBRARIES:%=$(USER_LIB_DIR)/lib%.a) $(shared_LIBRARIES:%=$(USER_LIB_DIR)/lib%.$(SOLIB_EXT))
+
+binary-pass-local: $(bin_PROGRAMS:%=$(USER_BIN_DIR)/%$(EXE_SUFFIX)) $(utils_PROGRAMS:%=$(USER_UTILS_DIR)/%$(EXE_SUFFIX)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%$(EXE_SUFFIX))
+
+# Special rules for CMETRIC generated headers
+
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call COMPILE_c_o_template,\
+               $(SOURCES_DIR)/$($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES),\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),)))
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call CMETRIC_o_h_template,\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),\
+               $(addprefix $(USER_INCLUDE_DIR)/,$(cmetrh)))))
+
+GEN_HEADERS+=$(cmetric_include_HEADERS:%=$(USER_INCLUDE_DIR)/%)
+
+GEN_HEADERS+=$(filter %.h,$(USER_IDLS:%.idl=%.h))
+
+# Generate rules for compilation of programs and libraries
+
+$(foreach prog,$(utils_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_UTILS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(test_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(bin_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR),$(EXE_SUFFIX))))
+
+$(foreach lib,$(lib_LIBRARIES),$(eval $(call LIBRARY_template,$(lib))))
+
+$(foreach lib,$(shared_LIBRARIES),$(eval $(call SOLIB_template,$(lib))))
+
+-include $(USER_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+# Kernel-space rules and templates to compile modules, libraries etc.
+
+ifdef KERN_RULE_TEMPLATES
+
+$(KERN_LIB_DIR)/kernel.mk: $(LINUX_DIR)/.config $(MAKERULES_DIR)/kernelcfg2mk
+       @$(QUIET_CMD_ECHO) "  KCFG2MK $$@"
+       $(Q) $(MAKERULES_DIR)/kernelcfg2mk $(LINUX_DIR) $(KERN_LIB_DIR)
+
+ifeq ($(CONFIG_RTLINUX),y)
+include $(RTL_DIR)/rtl.mk
+
+KERN_CC = $(CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+INCLUDES := -I $(KERN_INCLUDE_DIR) $(INCLUDE) $(rtlinux_INCLUDES) $(kernel_INCLUDES)
+#-DEXPORT_NO_SYMBOLS
+c_o_kern_COMPILE = $(KERN_CC) -idirafter $(kern_GCCLIB_DIR)/include $(INCLUDES)  $(CFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(CXX) $(INCLUDES) $(CXXFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := .o
+KERN_ARCH = $(ARCH)
+KERN_LD = $(LD)
+KERN_AR = $(AR)
+
+else # CONFIG_RTLINUX
+
+include $(KERN_LIB_DIR)/kernel.mk
+
+ifeq ($(LINUX_SRC),)
+LINUX_SRC = $(LINUX_DIR)
+endif
+kernel_INCLUDES += -I $(LINUX_DIR) -idirafter $(LINUX_SRC)/include/linux
+
+ifdef LINUX_CC
+KERN_CC = $(LINUX_CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(LINUX_CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+else
+KERN_CC = echo KERN_CC not defined - compilation skipped
+endif
+c_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+S_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_AFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := $(LINUX_MODULE_EXT)
+KERN_LDFLAGS = $(LINUX_LDFLAGS)
+ifdef LINUX_ARCH
+KERN_ARCH = $(LINUX_ARCH)
+else
+KERN_ARCH = echo KERN_ARCH not defined - skipped
+endif
+ifdef LINUX_LD
+KERN_LD = $(LINUX_LD)
+else
+KERN_LD = echo KERN_LD  not defined - skipped
+endif
+ifneq ($(LINUX_AR),)
+KERN_AR = $(LINUX_AR)
+else
+KERN_AR = $(AR)
+endif
+ifeq ($(LINUX_QUOTE_MODNAME),y)
+KERN_MQ=\"
+KERN_KBUILD_MODNAME=-D"KBUILD_MODNAME=((THIS_MODULE)!=NULL?(THIS_MODULE)->name:NULL)"
+endif
+endif # CONFIG_RTLINUX
+
+KERN_LOADLIBES += -L$(KERN_LIB_DIR) 
+
+KERN_LOADLIBES += $(rtlinux_LOADLIBES:%=-l%)
+KERN_LOADLIBES += $(kernel_LOADLIBES:%=-l%)
+
+
+
+# Check GCC version for kernel part of build
+ifndef kern_CC_MAJOR_VERSION
+kern_CC_MAJOR_VERSION := $(shell $(KERN_CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(kern_CC_MAJOR_VERSION),2)
+kern_CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+kern_CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+ifeq ($(KERN_EXE_SUFFIX),.ko)
+ifeq ($(wildcard $(LINUX_DIR)/scripts/mod/modpost),)
+KERN_MODPOST = $(LINUX_DIR)/scripts/modpost
+else
+KERN_MODPOST = $(LINUX_DIR)/scripts/mod/modpost
+endif
+KERN_MODULES_LINK_DIR = $(KERN_MODPOST_DIR)
+KERN_LINK_SUFFIX = .o
+else
+KERN_MODULES_LINK_DIR = $(KERN_MODULES_DIR)
+KERN_LINK_SUFFIX = $(KERN_EXE_SUFFIX)
+endif
+
+ifeq ($(LINUX_CONFIG_MODVERSIONS),y)
+MODPOST_OPTS += -m
+MODPOST_OPTS += -i $(LINUX_DIR)/Module.symvers
+ifneq ($(LINUX_BUILDHOST),) # this is not correct point, it should look for 2.6.17 kernel
+MODPOST_OPTS += -I $(KERN_LIB_DIR)/Module.symvers
+endif
+MODPOST_OPTS += -o $(KERN_LIB_DIR)/Module.symvers
+endif
+
+ifeq ($(LINUX_CONFIG_DEBUG_SECTION_MISMATCH),y)
+MODPOST_OPTS += -S
+endif
+
+ifeq ($(LINUX_CONFIG_MARKERS),y)
+MODPOST_OPTS += -K $(LINUX_DIR)/Module.markers
+MODPOST_OPTS += -M $(KERN_LIB_DIR)/Module.markers
+endif
+
+ifeq ($(LINUX_KBUILD_MODPOST_WARN),y)
+MODPOST_OPTS += -w
+endif
+
+ifneq ($(LINUX_BUILDHOST),)
+ifneq ($(LINUX_BUILDHOST),$(LINUX_ARCH))
+MODPOST_OPTS += -c
+endif
+endif
+
+define COMPILE_c_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CC [K]  $$@"
+       $(Q) if $$(c_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_cc_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CXX [K] $$@"
+       $(Q) if $$(cc_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_S_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  AS [K]  $$@"
+       $(Q) if $$(S_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define MODULE_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+# this is hack to build "__this_module" structure for 2.6.x kernels
+# modpost is used for that purpose now
+
+#$(1).mod.c:
+#      echo  "\
+#      #include <linux/version.h>@\
+#      #include <linux/module.h>@\
+#      #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5))@\
+#      #include <linux/vermagic.h>@\
+#      #include <linux/compiler.h>@\
+#      @\
+#      MODULE_INFO(vermagic, VERMAGIC_STRING);@\
+#      @\
+#      #undef unix@\
+#      struct module __this_module@\
+#      __attribute__((section(\".gnu.linkonce.this_module\"))) = {@\
+#       .name = __stringify(KBUILD_MODNAME),@\
+#       .init = init_module,@\
+#      #ifdef CONFIG_MODULE_UNLOAD@\
+#       .exit = cleanup_module,@\
+#      #endif@\
+#      };@\
+#      #endif@\
+#      " | tr @ \\n >$$@ 
+
+
+#$(eval $(call COMPILE_c_o_kern_template,$(1).mod.c,$(1).mod.o,-DKBUILD_MODNAME=$(1)))
+
+$(2)/$(1)$(KERN_LINK_SUFFIX): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LD [K]  $$@"
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) -r $$($(1)_OBJS) -L$$(kern_GCCLIB_DIR) $$($(1)_LIBS:%=-l%) $$(KERN_LOADLIBES) -Map $(KERN_OBJS_DIR)/$(1).mod.map -o $$@
+       @echo "$(2)/$(1)$(KERN_LINK_SUFFIX): \\" >$(KERN_OBJS_DIR)/$(1).mod.d
+       @sed -n -e 's/^LOAD \(.*\)$$$$/  \1  \\/p' $(KERN_OBJS_DIR)/$(1).mod.map  >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @echo >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @if [ "$(KERN_EXE_SUFFIX)" = ".ko" ] ; then \
+         echo $(1) >>$(KERN_MODPOST_DIR)/module-changes ; \
+         echo $(1) >$(KERN_MODPOST_DIR)/$(1).mod.stamp ; \
+       fi
+
+endef
+
+
+
+define LIBRARY_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+$(KERN_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR [K]  $$@"
+       $(Q) $(KERN_AR) rcs $$@ $$^
+endef
+
+
+ifdef LINUX_DIR
+
+kernel-lib-pass-local: $(kernel_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+kernel-mod-pass-local: $(kernel_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+$(foreach module,$(kernel_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(kernel_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+
+ifeq ($(CONFIG_RTLINUX),y)
+
+kernel-mod-pass-local: $(rtlinux_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+kernel-lib-pass-local: $(rtlinux_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+$(foreach module,$(rtlinux_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(rtlinux_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+ifeq ($(KERN_MODPOST_PASS),y)
+
+MODULES_LIST :=        $(wildcard *.mod.stamp)
+MODULES_LIST := $(MODULES_LIST:%.mod.stamp=%)
+
+define MODPOST_kern_template
+$(2) : $(1)$(KERN_LINK_SUFFIX) $(1).mod.c
+       @$(QUIET_CMD_ECHO) "  LD [M]  $$@"
+       $(Q) $$(cc_o_kern_COMPILE) -D"KBUILD_BASENAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -D"KBUILD_MODNAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -o $(1).mod.o -c $(1).mod.c
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) $(1)$(KERN_LINK_SUFFIX) $(1).mod.o -r -o $$@
+endef
+
+kernel-modpost-versions: $(wildcard $(LINUX_DIR)/Module.symvers)
+       @$(QUIET_CMD_ECHO) "  MODPOST    $(KERN_MODPOST_DIR)"
+       @echo  >$(KERN_MODPOST_DIR)/modpost-running
+       @rm -f $(KERN_MODPOST_DIR)/module-changes
+       $(Q) $(KERN_MODPOST) $(MODPOST_OPTS) $(MODULES_LIST:%=%$(KERN_LINK_SUFFIX))
+
+$(MODULES_LIST:%=%.mod.c) : kernel-modpost-versions
+
+kernel-modpost-pass-local: $(MODULES_LIST:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX))
+       @rm -f $(KERN_MODPOST_DIR)/modpost-running
+
+$(foreach module,$(MODULES_LIST),$(eval $(call MODPOST_kern_template,$(module),$(module:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX)))))
+
+endif
+
+-include $(KERN_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+
+# Kernel requires its own set of configuration header-files
+ifneq ($(kernel_LIBRARIES)$(rtlinux_LIBRARIES)$(kernel_MODULES)$(rtlinux_MODULES)$(kernel_HEADERS)$(rtlinux_HEADERS)$(kernel_HEADERS)$(rtlinux_HEADERS)$(nobase_kernel_HEADERS)$(nobase_rtlinux_HEADERS)$(renamed_kernel_HEADERS)$(renamed_rtlinux_HEADERS),)
+KERN_CONFIG_HEADERS_REQUIRED = y
+endif
+
+$(eval $(call omk_pass_template, kernel-lib-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_LIBRARIES)$(rtlinux_LIBRARIES)))
+$(eval $(call omk_pass_template, kernel-mod-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_MODULES)$(rtlinux_MODULES)))
+
+kernel-modpost-pass:
+       +@if [ -e "$(KERN_MODPOST_DIR)/module-changes" -o -e "$(KERN_MODPOST_DIR)/modpost-running" ] ; \
+       then \
+           $(MAKE) --no-print-directory -C $(KERN_MODPOST_DIR) \
+              -f $(SOURCES_DIR)/Makefile KERN_RULE_TEMPLATES=y KERN_MODPOST_PASS=y $(@:%=%-local) ; \
+       fi
+
+$(eval $(call omk_pass_template, library-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(lib_LIBRARIES)$(shared_LIBRARIES)))
+$(eval $(call omk_pass_template, binary-pass, $(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(bin_PROGRAMS)$(utils_PROGRAMS)$(test_PROGRAMS)))
+
+$(eval $(call omk_pass_template,clean,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,install,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,include-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,always))
+
+check-dir:
+       @$(call mkdir_def,$(USER_BUILD_DIR))
+       @$(call mkdir_def,$(KERN_BUILD_DIR))
+       @$(call mkdir_def,$(USER_INCLUDE_DIR))
+       @$(call mkdir_def,$(KERN_INCLUDE_DIR))
+       @$(call mkdir_def,$(USER_LIB_DIR))
+       @$(call mkdir_def,$(KERN_LIB_DIR))
+       @$(call mkdir_def,$(USER_BIN_DIR))
+       @$(call mkdir_def,$(USER_UTILS_DIR))
+       @$(call mkdir_def,$(USER_TESTS_DIR))
+       @$(call mkdir_def,$(KERN_MODULES_DIR))
+       @$(call mkdir_def,$(KERN_MODPOST_DIR))
+
+install-local:                 # TODO
+
+$(eval $(call include-pass-template,$(USER_INCLUDE_DIR),include))
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),kernel))
+ifeq ($(CONFIG_RTLINUX),y)
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),rtlinux))
+endif
+
+
+ifdef USER_RULE_TEMPLATES
+
+# User-space static libraries and applications object files
+
+USER_SOURCES := $(sort $(USER_SOURCES))
+
+USER_GEN_SOURCES := $(sort $(USER_GEN_SOURCES))
+
+#$(warning USER_SOURCES = $(USER_SOURCES))
+
+$(foreach src,$(filter %.c,$(USER_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+
+$(foreach src,$(filter %.c,$(USER_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.o),)))
+
+# User-space shared libraries object files
+
+SOLIB_SOURCES := $(sort $(SOLIB_SOURCES))
+
+SOLIB_GEN_SOURCES := $(sort $(SOLIB_GEN_SOURCES))
+
+#$(warning SOLIB_SOURCES = $(SOLIB_SOURCES))
+#$(warning SOLIB_GEN_SOURCES = $(SOLIB_GEN_SOURCES))
+
+$(foreach src,$(filter %.c,$(SOLIB_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cc,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cxx,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.S,$(SOLIB_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.c,$(SOLIB_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+# IDL compilation
+
+USER_IDLS := $(sort $(USER_IDLS))
+
+$(foreach src,$(filter %.idl,$(USER_IDLS)),$(eval $(call COMPILE_idl_template,$(SOURCES_DIR)/$(src),$(src:%.idl=%))))
+
+endif
+
+ifdef KERN_RULE_TEMPLATES
+
+KERN_SOURCES := $(sort $(KERN_SOURCES))
+
+#$(warning KERN_SOURCES = $(KERN_SOURCES))
+
+$(foreach src,$(filter %.c,$(KERN_SOURCES)),$(eval $(call COMPILE_c_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+endif
+
+clean-local: clean-custom
+       @echo Cleaning in $(KERN_OBJS_DIR) and $(USER_OBJS_DIR)
+       @rm -f $(KERN_OBJS_DIR)/*.o $(USER_OBJS_DIR)/*.[och] $(USER_OBJS_DIR)/*.lo\
+              $(KERN_OBJS_DIR)/*.d $(USER_OBJS_DIR)/*.d \
+              $(KERN_OBJS_DIR)/*.map $(USER_OBJS_DIR)/*.map \
+              $(KERN_OBJS_DIR)/*.mod.c \
+              $(kernel_MODULES:%=$(KERN_MODPOST_DIR)/%.*) \
+              $(LOCAL_CONFIG_H:%=$(KERN_OBJS_DIR)/%) \
+              $(LOCAL_CONFIG_H:%=$(USER_OBJS_DIR)/%)
+       @if [ -e $(KERN_LIB_DIR)/kernel.mk ] ; then \
+           touch -t 200001010101 $(KERN_LIB_DIR)/kernel.mk ; \
+       fi
+
+include-pass-submakes: extra-rules-subdirs
+
+# We must go to EXTRA_RULES_SUBDIRS beofre going to any other
+# directory, since the executables compiled in EXTRA_RULES_SUBDIRS
+# might be needed there.
+include-pass-this-dir $(foreach subdir,$(SUBDIRS),include-pass-$(subdir)-subdir): extra-rules-subdirs
+
+default: include-pass library-pass binary-pass
+ifndef OMIT_KERNEL_PASSES
+# Also make kernel passes if not disabled
+default: kernel-lib-pass kernel-pass
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@config_h
+# Syntax: $(call BUILD_CONFIG_H_template,<stamp_dir>,<header_file_path>,<list_of_options_to_export>,<header_barrier>)
+define BUILD_CONFIG_H_template
+
+$(addprefix $(1)/,$(notdir $(addsuffix .stamp,$(2)))) : $(CONFIG_FILES)
+       @$(QUIET_CMD_ECHO) "  CONFGEN $$(@:%.stamp=%)"
+       @if [ ! -d `dirname $(2).tmp` ] ; then \
+               mkdir -p `dirname $(2).tmp` ; fi
+       @echo "/* Automatically generated from */" > "$(2).tmp"
+       @echo "/* config files: $$(^:$(OUTPUT_DIR)/%=%) */" >> "$(2).tmp"
+       $(if $(DOXYGEN),@echo "/** @file */" >> "$(2).tmp")
+       @echo "#ifndef $(4)" >> "$(2).tmp"
+       @echo "#define $(4)" >> "$(2).tmp"
+       @( $(foreach x, $(shell echo '$($(3))' | tr 'x\t ' 'x\n\n' | sed -e 's/^\([^ =]*\)\(=[^ ]\+\|\)$$/\1/' ), \
+               echo '$(x).$($(x))' ; ) echo ; ) | \
+               sed -e '/^[^.]*\.n$$$$/d' -e '/^[^.]*\.$$$$/d' -e 's/^\([^.]*\)\.[ym]$$$$/\1.1/' | \
+               sed -n -e 's/^\([^.]*\)\.\(.*\)$$$$/#define \1 \2/p' \
+                 >> "$(2).tmp"
+       @echo "#endif /*$(4)*/" >> "$(2).tmp"
+       @touch "$$@"
+       @if cmp --quiet "$(2).tmp" "$(2)" ; then rm "$(2).tmp"; \
+       else mv "$(2).tmp" "$(2)" ; \
+       echo "Updated configuration $(2)" ; fi
+
+endef
+
+ifdef LOCAL_CONFIG_H
+
+# This must be declared after the default cflags are assigned!
+# Override is used to override command line assignemnt.
+override CFLAGS += -I $(USER_OBJS_DIR)
+override kernel_INCLUDES += -I $(KERN_OBJS_DIR)
+$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(USER_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+
+endif
+
+# Special rules for configuration exported headers
+
+#FIXME: The directory for headers should not be specified here.
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(addprefix $(USER_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+config_h_stamp_files = $(addprefix $(USER_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(config_h_stamp_files)
+
+ifneq ($(KERN_CONFIG_HEADERS_REQUIRED),)
+
+ifdef LOCAL_CONFIG_H
+$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(KERN_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+endif
+
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(addprefix $(KERN_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+kern_config_h_stamp_files = $(addprefix $(KERN_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(kern_config_h_stamp_files)
+
+endif
+
+clean-local: clean-local-config-h
+
+clean-local-config-h:
+       @$(foreach confh,$(config_h_stamp_files) $(kern_config_h_stamp_files),\
+           if [ -e $(confh) ] ; then rm $(confh) ; fi ; \
+       )
+
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@qt
+ifneq ($(QT_SUBDIRS),)
+
+.PHONY: qt-subpass clean-qt distclean-qt
+
+# Usage: $(call qt_makefile_template,<qt-subdir>)
+define qt_makefile_template
+$(SOURCES_DIR)/$(1)/Makefile: $(wildcard $(SOURCES_DIR)/$(1)/*.pro)
+       cd $(SOURCES_DIR)/$(1); $(QTDIR:%=%/bin/)qmake TOP_DIR=$(OUTPUT_DIR) \
+            RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) $(QTDIR:%=QTDIR=%) CC=$(CC) \
+            CXX=$(CXX) LIBS+="-L$(USER_LIB_DIR)" INCLUDEPATH+="$(USER_INCLUDE_DIR)"
+endef
+$(foreach dir,$(QT_SUBDIRS), $(eval $(call qt_makefile_template,$(dir))))
+
+qt-subpass: $(foreach dir,$(QT_SUBDIRS), $(SOURCES_DIR)/$(dir)/Makefile)
+       $(foreach dir,$(QT_SUBDIRS),\
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile || exit 1 ;)
+
+# Hook to binary pass
+binary-pass-submakes: qt-subpass
+
+# Hook to clean pass
+clean-local: clean-qt
+clean-qt:
+       +@$(foreach dir, $(QT_SUBDIRS), \
+               $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+               @$(QUIET_CMD_ECHO) "  CLEAN   $(dir)"; \
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile clean|| exit 1 ;))
+
+
+# Hook to distclean
+distclean: distclean-qt
+
+# TODO: Add distclean-qt-pass to handle QT_SUBDIRS in the whole
+# tree. This way we only distclean toplevel subdirs.
+distclean-qt:
+       +@$(foreach dir, $(QT_SUBDIRS), \
+               $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+               @$(QUIET_CMD_ECHO) "  DISTCLEAN $(dir)"; \
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile distclean|| exit 1 ;))
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@sources-list
+# Rules that creates the list of files which are used during
+# compilation. The list reflects conditional compilation depending on
+# config.omk and other variables.
+
+SOURCES_LIST_FN=sources.txt
+ifndef SOURCES_LIST
+SOURCES_LIST_DIR:=$(RELATIVE_DIR)
+SOURCES_LIST:=$(OUTPUT_DIR)/$(SOURCES_LIST_DIR)/$(SOURCES_LIST_FN)
+SOURCES_LIST_D := $(LOCAL_BUILD_DIR)/$(SOURCES_LIST_FN).d
+export SOURCES_LIST SOURCES_LIST_DIR SOURCES_LIST_D
+endif
+
+ifeq ($(MAKECMDGOALS),sources-list)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),TAGS)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),tags)
+NEED_SOURCES_LIST=y
+endif
+
+ifeq ($(NEED_SOURCES_LIST),y) # avoid execution of find command bellow if it is not useful
+.PHONY: sources-list
+sources-list: $(SOURCES_LIST)
+
+$(SOURCES_LIST): $(CONFIG_FILES) $(shell find -name $(MAKEFILE_OMK))
+       @$(call mkdir_def,$(dir $(SOURCES_LIST_D)))
+       @echo -n "" > "$(SOURCES_LIST).tmp"
+       @echo -n "" > "$(SOURCES_LIST_D).tmp"
+       @$(MAKE) --no-print-directory sources-list-pass
+       @echo "# Automatically generated list of files in '$(RELATIVE_DIR)' that are used during OMK compilation" > "$(SOURCES_LIST).tmp2"
+       @cat "$(SOURCES_LIST).tmp"|sort|uniq >> "$(SOURCES_LIST).tmp2"
+       @rm "$(SOURCES_LIST).tmp"
+       @mv "$(SOURCES_LIST).tmp2" "$(SOURCES_LIST)"
+       @echo "$(SOURCES_LIST): \\" > "$(SOURCES_LIST_D).tmp2"
+       @cat "$(SOURCES_LIST_D).tmp"|grep -v "$(SOURCES_LIST_D).tmp"|sort|uniq|\
+               sed -e 's/$$/\\/' >> "$(SOURCES_LIST_D).tmp2"
+       @rm "$(SOURCES_LIST_D).tmp"
+       @mv "$(SOURCES_LIST_D).tmp2" "$(SOURCES_LIST_D)"
+endif
+
+$(eval $(call omk_pass_template,sources-list-pass,$$(LOCAL_BUILD_DIR),,always))
+
+sources-list-pass-local:
+       @$(foreach m,$(MAKEFILE_LIST),echo '  $(m)' >> "$(SOURCES_LIST_D).tmp";)
+       @$(foreach h,$(include_HEADERS) $(nobase_include_HEADERS) $(kernel_HEADERS),\
+         echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(h)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach ch,$(config_include_HEADERS), \
+         echo "$(USER_INCLUDE_DIR:$(OUTPUT_DIR)/$(addsuffix /,$(SOURCES_LIST_DIR))%=%)/$(ch)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach h,$(renamed_include_HEADERS),echo '$(h)'|sed -e 's|\(.*\)->.*|$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))\1|' >> "$(SOURCES_LIST).tmp";)
+       @$(foreach bin,$(lib_LIBRARIES) $(shared_LIBRARIES) $(bin_PROGRAMS) $(test_PROGRAMS) $(utils_PROGRAMS) \
+         $(kernel_LIBRARIES) $(rtlinux_LIBRARIES) $(kernel_MODULES),\
+         $(foreach src,$(filter-out %.o,$($(bin)_SOURCES)),echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(src)" >> "$(SOURCES_LIST).tmp";))
+
+############ TAGS ###########
+
+ifeq ($(MAKECMDGOALS),TAGS)
+ETAGS=etags
+TAGS_CMD = $(ETAGS)
+TAGS: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+ifeq ($(MAKECMDGOALS),tags) 
+CTAGS=ctags -N
+TAGS_CMD = $(CTAGS)
+tags: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+export TAGS_CMD
+
+ifeq ($(MAKECMDGOALS),do-tags)
+.PHONY: do-tags
+do-tags: $(shell sed -e '/^\#/d' $(SOURCES_LIST))
+       @$(QUIET_CMD_ECHO) "  TAGS    $(SOURCES_LIST_FN)"
+       $(Q)$(TAGS_CMD) $^
+endif
+
+############ CSCOPE ###########
+
+cscope: $(SOURCES_LIST)
+       @$(QUIET_CMD_ECHO) "  CSCOPE  < $(SOURCES_LIST_FN)"
+       $(Q)sed -e '/^#/d' $(SOURCES_LIST)|cscope -b -i-
+#FIXME: see doc to -i in cscope(1)
+
+# Local Variables:
+# mode:makefile
+# End:
diff --git a/build/marte/config.target b/build/marte/config.target
new file mode 100644 (file)
index 0000000..771e7f1
--- /dev/null
@@ -0,0 +1,54 @@
+# -*- makefile -*-
+# Config file for compilation by OMK for Marte OS target
+
+# You can override this variable in config.omk
+MARTE_PATH=$(firstword $(wildcard $(HOME)/frescor/marte/ $(HOME)/marte/ /usr/src/marte))
+
+export PLATFORM=MARTE_OS
+
+# Create symbolic links to headers instead of copying them. Useful
+# during development.
+LN_HEADERS=y
+
+# We do not want to overwrite original FRESCOR Makefiles
+USE_LEAF_MAKEFILES=n
+
+########################################
+# Setting of compiler
+########################################
+
+# This doesn't work with MARTE OS 1.7 since mgcc script eats multiple
+# -M options. Current version of mgcc works correctly.
+CC=$(MARTE_PATH)/utils/mgcc
+CFLAGS=-Wall -g  -O1  -Wuninitialized -D$(PLATFORM)
+
+ifneq ($(V),2)
+export MGCC_QUIET=y
+endif
+
+# # Instead, with MARTE OS 1.7, we call normal gcc with parameters which mgcc adds
+
+# # List of variables to import from Marte's global.pl
+# MARTE_VARS = MPATH GNAT_PATH ARCH_LD_OPTS CRTI_0 CRTN_O INCLUDES LIBS        \
+#           LIBS_PATH ARCH_GCC_OPTS WRAPPER_MAIN_C_O                   \
+#           WRAPPER_MAIN_CPP_O _EXIT_O
+
+# # Acquire Marte configuration and store it in marte.mk
+# $(MAKERULES_DIR)/marte.mk: $(MARTE_PATH)/utils/globals.pl
+#      @$(QUIET_CMD_ECHO) "  CREATE  marte.mk"
+#      $(Q)perl -e 'require "$(MARTE_PATH)/utils/globals.pl"; foreach (qw/$(MARTE_VARS)/) {print "$$_=$${$$_}\n";}' > $@.tmp
+#      $(Q)mv $@.tmp $@
+
+# # Import Marte configuration as make variables
+# -include $(MAKERULES_DIR)/marte.mk
+
+# # Use the compiler configured for Marte
+# CC=$(GNAT_PATH)/../../../../bin/gcc
+
+# distclean: distclean-marte.mk
+# distclean-marte.mk:
+#      @$(QUIET_CMD_ECHO) "  RM      marte.mk"
+#      $(Q)rm -f $(MAKERULES_DIR)/marte.mk
+
+# CFLAGS=$(ARCH_GCC_OPTS) -Wall -Wuninitialized -g -gstabs+ -O1 -D$(PLATFORM)
+# LDFLAGS=$(ARCH_LD_OPTS) $(CRTI_0) $(WRAPPER_MAIN_C_O) $(_EXIT_O) $(LIBS_PATH) $(LIBS) $(CRTN_O)
diff --git a/build/marte/create-links b/build/marte/create-links
new file mode 100755 (executable)
index 0000000..9a0fc93
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Usage: ./create-links [path/to/frescor/root]
+#
+# path/to/frescor/root defaults to ../..
+
+LINKS="
+dtm
+fna
+fosa
+frsh
+fsa
+utils
+"
+
+FRESCOR_SRC=${1:-../..}
+
+for link in $LINKS; do
+       ln -s $FRESCOR_SRC/$link .
+done
+
diff --git a/doc/RelNotes-0.1.1.txt b/doc/RelNotes-0.1.1.txt
new file mode 100644 (file)
index 0000000..d4fd8aa
--- /dev/null
@@ -0,0 +1,12 @@
+FRSH/FORB 0.1.1
+===============
+
+This is mostly a bug-fix release. The main differences from version
+0.1 are:
+
+- Added frsh_get_local_cpu_id() which returns either compiled in local
+  CPU ID or, if set, the value of FRSH_CPU_ID environment variable.
+  This function is used by CPU resource managers/allocators and should
+  also be used by applications.
+- A few bugs fixed in BFQ, Cgroup and FWP resource managers.
+- Up-to-date Makefile.rules
diff --git a/doc/RelNotes-0.1.txt b/doc/RelNotes-0.1.txt
new file mode 100644 (file)
index 0000000..ab05abe
--- /dev/null
@@ -0,0 +1,26 @@
+FRSH/FORB 0.1
+=============
+
+This is the first official release of FRSH/FORB resource reservation
+framework for real-time and distributed applications.
+
+The main differences from the version available at the end of FRESCOR
+project are the following:
+
+- FRSH WLAN Protocol (FWP) was reworked quite a lot. 
+  * It contains new version of VRES budgeting which handles correctly
+    all corner cases. 
+  * FWP overhead was decreased significantly by allowing sending of
+    packets directly from application threads instead of VRES threads,
+    which are now used only if the budget is exhausted. 
+  * Synchronous send operation was implemented.
+  * New application fwp-timing was developed to measure communication
+    delays and packet looses. It showed that the previously mentioned
+    changes improved FWP parameters.
+- FRSH API was slightly changed to remove problematic things.
+  See commit b5508fb2d706b33491fbde62a675432300b43542.
+- Improved logging. Every log message is now prefixed by the name of
+  the process.
+- Several bugs were fixed:
+  * Race condition in registration of allocators.
+  * Incorrect block id in disk BFQ resource
diff --git a/scripts/reselase.sh b/scripts/reselase.sh
new file mode 100755 (executable)
index 0000000..480cda7
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+cd ./$(git rev-parse --show-cdup)
+
+if ! git submodule foreach --quiet 'git diff-files --quiet && git diff-index --quiet HEAD'
+then
+    echo >&2 "Submodules are not clean"
+    exit 1
+fi
+
+if ! git diff-files --quiet || ! git diff-index --quiet HEAD
+then
+    echo >&2 "The work tree is not clean"
+    exit 1
+fi
+
+NAME=${NAME:-frsh-forb}
+VERSION=`git describe|sed -e s/^v//`
+
+( git submodule foreach --quiet 'git ls-files|sed -e "s|^|$path/|"'; \
+    git ls-files -s|grep -v ^16|awk '{print $4;}' ) \
+    | grep -v '\(.gitignore\|.gitmodules\)' | \
+tar -czf ${NAME}-${VERSION}.tar.gz --files-from - --transform "s|^\([^\.].*\)|${NAME}-${VERSION}/\1|"
similarity index 100%
rename from COPYING
rename to src/fna/COPYING
similarity index 100%
rename from Changelog
rename to src/fna/Changelog
similarity index 100%
rename from INSTALL
rename to src/fna/INSTALL
similarity index 100%
rename from Makefile
rename to src/fna/Makefile
similarity index 100%
rename from Makefile.omk
rename to src/fna/Makefile.omk
diff --git a/src/fna/README b/src/fna/README
new file mode 100644 (file)
index 0000000..8b76ec5
--- /dev/null
@@ -0,0 +1,48 @@
+FNA
+=====================
+Name:
+FNA
+
+Version:
+May 2008
+
+Status:
+Alpha
+
+Authors:
+Daniel Sangorrin [daniel.sangorrin@unican.es] (UC),
+Michael Gonzalez Harbour [mgh@unican.es] (UC)
+Martin Molnar (CTU)
+Michal Sojka (CTU)
+
+Licence:
+FRESCOR Lincece (see COPYING)
+
+Brief description:
+This is FNA (Frescor Network Adaptation layer) module, the layer that allows
+to plug-in different network protocols to FRESCOR by means of a clear interface.
+
+URL:
+svn co http://www.frescor.org/private/svn/frescor/fna/trunk/
+
+Bugs:
+See TODO
+
+Description:
+
+This is FNA (Frescor Network Adaptation layer) module, the layer that allows
+to plug-in different network protocols to FRESCOR by means of a clear interface.
+
+- README: This file
+
+- COPYING: FRESCOR license
+
+- INSTALL: Installation instructions
+
+- include/: FNA API C header files.
+
+- src/ : source code of FNA that is common to all protocols
+
+- src_xxx/ : source code of 'xxx' protocols
+
+- doc/: documentation directory
similarity index 100%
rename from TODO
rename to src/fna/TODO
similarity index 100%
rename from config.mk_example
rename to src/fna/config.mk_example
similarity index 100%
rename from include/fna.h
rename to src/fna/include/fna.h
similarity index 100%
rename from rules.mk
rename to src/fna/rules.mk
similarity index 100%
rename from src/Makefile
rename to src/fna/src/Makefile
similarity index 100%
rename from src_frescan/TODO
rename to src/fna/src_frescan/TODO
similarity index 100%
rename from src_rtep/Makefile
rename to src/fna/src_rtep/Makefile
similarity index 100%
rename from src_unix/Makefile
rename to src/fna/src_unix/Makefile
diff --git a/src/forb/.gitignore b/src/forb/.gitignore
new file mode 100644 (file)
index 0000000..3fb95a8
--- /dev/null
@@ -0,0 +1,11 @@
+_build/
+_compiled/
+*~
+config.omk-default
+cscope.*
+config.omk
+sources.txt
+TAGS
+*.kdevelop*
+.emacs*
+*.kdevses
diff --git a/src/forb/COPYING b/src/forb/COPYING
new file mode 100644 (file)
index 0000000..e37680c
--- /dev/null
@@ -0,0 +1,280 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           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 Lesser 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
diff --git a/src/forb/Doxyfile b/src/forb/Doxyfile
new file mode 100644 (file)
index 0000000..c9f6d9d
--- /dev/null
@@ -0,0 +1,1417 @@
+# Doxyfile 1.5.6
+
+# 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 (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "FORB (Frescor Object Request Broker)"
+
+# 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       = doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# 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: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, 
+# and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# 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
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# 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. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# 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 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 regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_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         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = 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
+
+# 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                = 
+
+# 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  = YES
+
+# 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 OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = 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   = YES
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# 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            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# 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
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# 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     = YES
+
+# 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 classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# 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
+
+# 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 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# 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 SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = 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 the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# 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
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# 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 consists 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 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
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# 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
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# 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. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+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
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# 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 *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+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              = YES
+
+# 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. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# 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 <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# 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 (i.e. when SOURCE_BROWSER is set to YES).
+
+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. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+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
+
+# 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 REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = 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       = NO
+
+#---------------------------------------------------------------------------
+# 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. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+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 compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = 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 directory.
+
+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 CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# 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             = NO
+
+# 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
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, 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, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature. Other possible values 
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hiererachy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW      = NONE
+
+# 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
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+#---------------------------------------------------------------------------
+# 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         = YES
+
+# 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           = YES
+
+# 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
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = 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 optimized 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 assignments. 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           = NO
+
+# 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.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML 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 `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# 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 Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# 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_DEFINED 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. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF 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::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+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 superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = NO
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# 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
+
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
+# 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 the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# 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 CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# 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
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = 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 in 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 DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is enabled by default, which results in a transparent 
+# background. Warning: Depending on the platform used, enabling this option 
+# may lead to badly anti-aliased labels on the edges of a graph (i.e. they 
+# become hard to read).
+
+DOT_TRANSPARENT        = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# 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 intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions 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
diff --git a/src/forb/Makefile b/src/forb/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/forb/Makefile.omk b/src/forb/Makefile.omk
new file mode 100644 (file)
index 0000000..e34fb4a
--- /dev/null
@@ -0,0 +1,2 @@
+SUBDIRS = tests-idl src
+EXTRA_RULES_SUBDIRS = forb-idl
diff --git a/src/forb/README b/src/forb/README
new file mode 100644 (file)
index 0000000..f6969c0
--- /dev/null
@@ -0,0 +1,22 @@
+Compilation
+===========
+
+1. Download FRESCOR SVN repositories fosa and omk-build
+
+2. Download ulut (from
+   http://sourceforge.net/project/showfiles.php?group_id=118937&package_id=130840)
+
+3. Create symbolic links to forb, fosa and ulut sources inside
+   omk-build/aquosa:
+
+   cd omk-build/aquosa
+   ln -s some-path/fosa .
+   ln -s some-path/ulut .
+   ln -s path-to-this-directory/forb .
+
+3. Configure the sources:
+       make default-config
+
+5. Compile it:
+       make    
+       
diff --git a/src/forb/TODO b/src/forb/TODO
new file mode 100644 (file)
index 0000000..8c14cc8
--- /dev/null
@@ -0,0 +1,10 @@
+* Add forb_init() parameters: argc, argv and orb_id
+
+* More flexible handling of log messages (dynamic registration,
+   parsing of command line parameters).
+
+* Add FNA as transport protocol (probably with some reliable protocol
+   on top of FNA)
+
+* Add routing layer
+   
diff --git a/src/forb/doc/forb.vpp b/src/forb/doc/forb.vpp
new file mode 100644 (file)
index 0000000..1ea834e
Binary files /dev/null and b/src/forb/doc/forb.vpp differ
diff --git a/src/forb/forb-idl/Makefile b/src/forb/forb-idl/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/forb/forb-idl/Makefile.am b/src/forb/forb-idl/Makefile.am
new file mode 100644 (file)
index 0000000..b45cae2
--- /dev/null
@@ -0,0 +1,46 @@
+bin_PROGRAMS = orbit-idl-2
+
+orbit_backends_dir = $(libdir)/orbit-2.0/idl-backends
+
+INCLUDES =                                                     \
+       -I$(top_builddir)                                       \
+       -I$(top_builddir)/include                               \
+       -I$(top_srcdir)                                         \
+       -I$(top_srcdir)/include                                 \
+       -DORBIT_BACKENDS_DIR="\"$(orbit_backends_dir)\""        \
+       -DVERSION=\"$(ORBIT_VERSION)\"                          \
+       -DORBIT2_INTERNAL_API                                   \
+       $(WARN_CFLAGS)                                          \
+       $(DISABLE_DEPRECATED_CFLAGS)                            \
+       $(ORBIT_IDL_CFLAGS)
+
+orbit_idl_2_LDADD =                     \
+       $(ORBIT_IDL_LIBS)               \
+       $(LIBM)
+
+orbit_idl_2_SOURCES =                  \
+       orbit-idl-main.c                \
+       orbit-idl-driver.c              \
+       orbit-idl-backend.c             \
+       orbit-idl-backend.h             \
+       orbit-idl-utils.c               \
+       orbit-idl2.h                    \
+       orbit-idl3-types.h              \
+        orbit-idl-c-backend.h          \
+        orbit-idl-c-backend.c          \
+        orbit-idl-c-stubs.c            \
+        orbit-idl-c-skels.c            \
+        orbit-idl-c-headers.c          \
+        orbit-idl-c-common.c           \
+       orbit-idl-c-imodule.c           \
+        orbit-idl-c-skelimpl.c         \
+        orbit-idl-c-utils.c            \
+        orbit-idl-c-typecode.c         \
+        orbit-idl-c-deps.c             \
+       orbit-idl2.h
+
+orbitidlincludedir = $(includedir)/orbit-2.0/orbit-idl
+orbitidlinclude_HEADERS = orbit-idl-backend.h
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = ORBit-idl-2.0.pc
diff --git a/src/forb/forb-idl/Makefile.in b/src/forb/forb-idl/Makefile.in
new file mode 100644 (file)
index 0000000..e7fb770
--- /dev/null
@@ -0,0 +1,614 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = orbit-idl-2$(EXEEXT)
+subdir = src/idl-compiler
+DIST_COMMON = $(orbitidlinclude_HEADERS) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in $(srcdir)/ORBit-idl-2.0.pc.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = ORBit-idl-2.0.pc
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" \
+       "$(DESTDIR)$(orbitidlincludedir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_orbit_idl_2_OBJECTS = orbit-idl-main.$(OBJEXT) \
+       orbit-idl-driver.$(OBJEXT) orbit-idl-backend.$(OBJEXT) \
+       orbit-idl-utils.$(OBJEXT) orbit-idl-c-backend.$(OBJEXT) \
+       orbit-idl-c-stubs.$(OBJEXT) orbit-idl-c-skels.$(OBJEXT) \
+       orbit-idl-c-headers.$(OBJEXT) orbit-idl-c-common.$(OBJEXT) \
+       orbit-idl-c-imodule.$(OBJEXT) orbit-idl-c-skelimpl.$(OBJEXT) \
+       orbit-idl-c-utils.$(OBJEXT) orbit-idl-c-typecode.$(OBJEXT) \
+       orbit-idl-c-deps.$(OBJEXT)
+orbit_idl_2_OBJECTS = $(am_orbit_idl_2_OBJECTS)
+am__DEPENDENCIES_1 =
+orbit_idl_2_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+       $(LDFLAGS) -o $@
+SOURCES = $(orbit_idl_2_SOURCES)
+DIST_SOURCES = $(orbit_idl_2_SOURCES)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+pkgconfigDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(pkgconfig_DATA)
+orbitidlincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(orbitidlinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkglibdir = @pkglibdir@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISABLE_DEPRECATED_CFLAGS = @DISABLE_DEPRECATED_CFLAGS@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GLIB_REQUIRED = @GLIB_REQUIRED@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBIDL_REQUIRED = @LIBIDL_REQUIRED@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINC_CFLAGS = @LINC_CFLAGS@
+LINC_LIBS = @LINC_LIBS@
+LN_S = @LN_S@
+LOCAL_LINC_CFLAGS = @LOCAL_LINC_CFLAGS@
+LOCAL_LINC_LIBS = @LOCAL_LINC_LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+LT_VERSION = @LT_VERSION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MINGW_LDFLAGS = @MINGW_LDFLAGS@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+ORBIT_ALIGNOF_CORBA_BOOLEAN = @ORBIT_ALIGNOF_CORBA_BOOLEAN@
+ORBIT_ALIGNOF_CORBA_CHAR = @ORBIT_ALIGNOF_CORBA_CHAR@
+ORBIT_ALIGNOF_CORBA_DOUBLE = @ORBIT_ALIGNOF_CORBA_DOUBLE@
+ORBIT_ALIGNOF_CORBA_FLOAT = @ORBIT_ALIGNOF_CORBA_FLOAT@
+ORBIT_ALIGNOF_CORBA_LONG = @ORBIT_ALIGNOF_CORBA_LONG@
+ORBIT_ALIGNOF_CORBA_LONG_DOUBLE = @ORBIT_ALIGNOF_CORBA_LONG_DOUBLE@
+ORBIT_ALIGNOF_CORBA_LONG_LONG = @ORBIT_ALIGNOF_CORBA_LONG_LONG@
+ORBIT_ALIGNOF_CORBA_OCTET = @ORBIT_ALIGNOF_CORBA_OCTET@
+ORBIT_ALIGNOF_CORBA_POINTER = @ORBIT_ALIGNOF_CORBA_POINTER@
+ORBIT_ALIGNOF_CORBA_SHORT = @ORBIT_ALIGNOF_CORBA_SHORT@
+ORBIT_ALIGNOF_CORBA_STRUCT = @ORBIT_ALIGNOF_CORBA_STRUCT@
+ORBIT_ALIGNOF_CORBA_WCHAR = @ORBIT_ALIGNOF_CORBA_WCHAR@
+ORBIT_CFLAGS = @ORBIT_CFLAGS@
+ORBIT_IDL_CFLAGS = @ORBIT_IDL_CFLAGS@
+ORBIT_IDL_LIBS = @ORBIT_IDL_LIBS@
+ORBIT_LIBS = @ORBIT_LIBS@
+ORBIT_MAJOR_VERSION = @ORBIT_MAJOR_VERSION@
+ORBIT_MICRO_VERSION = @ORBIT_MICRO_VERSION@
+ORBIT_MINOR_VERSION = @ORBIT_MINOR_VERSION@
+ORBIT_NAME_CFLAGS = @ORBIT_NAME_CFLAGS@
+ORBIT_NAME_LIBS = @ORBIT_NAME_LIBS@
+ORBIT_SERIAL = @ORBIT_SERIAL@
+ORBIT_VERSION = @ORBIT_VERSION@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+orbit_backends_dir = $(libdir)/orbit-2.0/idl-backends
+INCLUDES = \
+       -I$(top_builddir)                                       \
+       -I$(top_builddir)/include                               \
+       -I$(top_srcdir)                                         \
+       -I$(top_srcdir)/include                                 \
+       -DORBIT_BACKENDS_DIR="\"$(orbit_backends_dir)\""        \
+       -DVERSION=\"$(ORBIT_VERSION)\"                          \
+       -DORBIT2_INTERNAL_API                                   \
+       $(WARN_CFLAGS)                                          \
+       $(DISABLE_DEPRECATED_CFLAGS)                            \
+       $(ORBIT_IDL_CFLAGS)
+
+orbit_idl_2_LDADD = \
+       $(ORBIT_IDL_LIBS)               \
+       $(LIBM)
+
+orbit_idl_2_SOURCES = \
+       orbit-idl-main.c                \
+       orbit-idl-driver.c              \
+       orbit-idl-backend.c             \
+       orbit-idl-backend.h             \
+       orbit-idl-utils.c               \
+       orbit-idl2.h                    \
+       orbit-idl3-types.h              \
+        orbit-idl-c-backend.h          \
+        orbit-idl-c-backend.c          \
+        orbit-idl-c-stubs.c            \
+        orbit-idl-c-skels.c            \
+        orbit-idl-c-headers.c          \
+        orbit-idl-c-common.c           \
+       orbit-idl-c-imodule.c           \
+        orbit-idl-c-skelimpl.c         \
+        orbit-idl-c-utils.c            \
+        orbit-idl-c-typecode.c         \
+        orbit-idl-c-deps.c             \
+       orbit-idl2.h
+
+orbitidlincludedir = $(includedir)/orbit-2.0/orbit-idl
+orbitidlinclude_HEADERS = orbit-idl-backend.h
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = ORBit-idl-2.0.pc
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  src/idl-compiler/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  src/idl-compiler/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+ORBit-idl-2.0.pc: $(top_builddir)/config.status $(srcdir)/ORBit-idl-2.0.pc.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-binPROGRAMS: $(bin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         if test -f $$p \
+            || test -f $$p1 \
+         ; then \
+           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+         else :; fi; \
+       done
+
+uninstall-binPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+         echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+         rm -f "$(DESTDIR)$(bindir)/$$f"; \
+       done
+
+clean-binPROGRAMS:
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         echo " rm -f $$p $$f"; \
+         rm -f $$p $$f ; \
+       done
+orbit-idl-2$(EXEEXT): $(orbit_idl_2_OBJECTS) $(orbit_idl_2_DEPENDENCIES) 
+       @rm -f orbit-idl-2$(EXEEXT)
+       $(LINK) $(orbit_idl_2_OBJECTS) $(orbit_idl_2_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-backend.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-backend.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-deps.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-headers.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-imodule.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-skelimpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-skels.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-stubs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-typecode.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-utils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-driver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-utils.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+install-pkgconfigDATA: $(pkgconfig_DATA)
+       @$(NORMAL_INSTALL)
+       test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
+       @list='$(pkgconfig_DATA)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         f=$(am__strip_dir) \
+         echo " $(pkgconfigDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
+         $(pkgconfigDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgconfigdir)/$$f"; \
+       done
+
+uninstall-pkgconfigDATA:
+       @$(NORMAL_UNINSTALL)
+       @list='$(pkgconfig_DATA)'; for p in $$list; do \
+         f=$(am__strip_dir) \
+         echo " rm -f '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
+         rm -f "$(DESTDIR)$(pkgconfigdir)/$$f"; \
+       done
+install-orbitidlincludeHEADERS: $(orbitidlinclude_HEADERS)
+       @$(NORMAL_INSTALL)
+       test -z "$(orbitidlincludedir)" || $(MKDIR_P) "$(DESTDIR)$(orbitidlincludedir)"
+       @list='$(orbitidlinclude_HEADERS)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         f=$(am__strip_dir) \
+         echo " $(orbitidlincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(orbitidlincludedir)/$$f'"; \
+         $(orbitidlincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(orbitidlincludedir)/$$f"; \
+       done
+
+uninstall-orbitidlincludeHEADERS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(orbitidlinclude_HEADERS)'; for p in $$list; do \
+         f=$(am__strip_dir) \
+         echo " rm -f '$(DESTDIR)$(orbitidlincludedir)/$$f'"; \
+         rm -f "$(DESTDIR)$(orbitidlincludedir)/$$f"; \
+       done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
+       mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+         test -n "$$unique" || unique=$$empty_fix; \
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+           $$tags $$unique; \
+       fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+       list='$(DISTFILES)'; \
+         dist_files=`for file in $$list; do echo $$file; done | \
+         sed -e "s|^$$srcdirstrip/||;t" \
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+       case $$dist_files in \
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+                          sort -u` ;; \
+       esac; \
+       for file in $$dist_files; do \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         if test -d $$d/$$file; then \
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(DATA) $(HEADERS)
+installdirs:
+       for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(orbitidlincludedir)"; do \
+         test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+       done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-orbitidlincludeHEADERS install-pkgconfigDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-orbitidlincludeHEADERS \
+       uninstall-pkgconfigDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+       clean-generic clean-libtool ctags distclean distclean-compile \
+       distclean-generic distclean-libtool distclean-tags distdir dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-binPROGRAMS install-data install-data-am install-dvi \
+       install-dvi-am install-exec install-exec-am install-html \
+       install-html-am install-info install-info-am install-man \
+       install-orbitidlincludeHEADERS install-pdf install-pdf-am \
+       install-pkgconfigDATA install-ps install-ps-am install-strip \
+       installcheck installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags uninstall uninstall-am uninstall-binPROGRAMS \
+       uninstall-orbitidlincludeHEADERS uninstall-pkgconfigDATA
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/forb/forb-idl/Makefile.omk b/src/forb/forb-idl/Makefile.omk
new file mode 100644 (file)
index 0000000..657ae33
--- /dev/null
@@ -0,0 +1,19 @@
+bin_PROGRAMS = forb-idl
+
+#GLIB_FLAGS := $(shell pkg-config --cflags glib-2.0)
+IDL_FLAGS := $(shell pkg-config --cflags libIDL-2.0)
+CFLAGS += $(IDL_FLAGS) -DFORB_BACKENDS_DIR=\"/orbit-backend-dir\" -DVERSION=\"0.1\"
+CFLAGS := $(filter-out -fmudflapth,$(CFLAGS))
+LDFLAGS := $(filter-out -fmudflapth,$(LDFLAGS))
+LDFLAGS := $(filter-out -lmudflapth,$(LDFLAGS))
+
+forb-idl_SOURCES = forb-idl-backend.c forb-idl-backend.h       \
+                  forb-idl-c-backend.c forb-idl-c-backend.h    \
+                  forb-idl-c-common.c forb-idl-c-deps.c        \
+                  forb-idl-c-headers.c forb-idl-c-imodule.c    \
+                  forb-idl-c-skelimpl.c forb-idl-c-skels.c     \
+                  forb-idl-c-stubs.c forb-idl-c-typecode.c     \
+                  forb-idl-c-utils.c forb-idl-driver.c         \
+                  forb-idl-main.c forb-idl-utils.c forb-idl2.h \
+                  forb-idl3-types.h
+forb-idl_LIBS = IDL-2 glib-2.0 
diff --git a/src/forb/forb-idl/Makefile.rules b/src/forb/forb-idl/Makefile.rules
new file mode 100644 (file)
index 0000000..e5b6684
--- /dev/null
@@ -0,0 +1,1323 @@
+#                   Version for Linux/RTLinux builds.        #OMK@linux
+#
+#  Makefile.rules - OCERA make framework common project rules -*- makefile -*- #OMK@base
+#
+#  (C) Copyright 2003 by Pavel Pisa - OCERA team member
+#  (C) Copyright 2006 by Michal Sojka - Czech Technical University, FEE, DCE
+#
+#  Homepage: http://rtime.felk.cvut.cz/omk/
+#
+# The OMK build system is distributed under the GNU General Public
+# License.  See file COPYING for details.
+#
+# input variables
+# V                .. if set to 1, full command text is shown else short form is used
+# W                .. whole tree - if set to 1, make is always called from the top-level directory
+# SUBDIRS          .. list of subdirectories intended for make from actual directory
+# default_CONFIG   .. list of default config assignments CONFIG_XXX=y/n ...
+# LN_HEADERS       .. if "y", header files are symbolicaly linked instead of copied. #OMK@include
+#                                                            #OMK@linux
+# input variables
+# lib_LIBRARIES    .. list of the user-space libraries
+# shared_LIBRARIES .. list of the user-space shared libraries
+# kernel_LIBRARIES .. list of the kernel-space libraries
+# rtlinux_LIBRARIES.. list of the RT-Linux kernel-space libraries
+# include_HEADERS  .. list of the user-space public header files
+# nobase_include_HEADERS .. public headers copied even with directory part
+# renamed_include_HEADERS .. public headers copied to the different target name
+# kernel_HEADERS   .. list of the kernel-space public header files
+# rtlinux_HEADERS  .. list of the RT-Linux kernel-space public header files
+# bin_PROGRAMS     .. list of the require binary programs
+# utils_PROGRAMS   .. list of the development utility programs
+# test_PROGRAMS    .. list of the testing programs
+# kernel_MODULES   .. list of the kernel side modules/applications
+# rtlinux_MODULES  .. list of RT-Linux the kernel side modules/applications
+# xxx_SOURCES      .. list of specific target sources
+# xxx_LIBS         .. list of specific target libraries
+# INCLUDES         .. additional include directories and defines for user-space
+# kernel_INCLUDES  .. additional include directories and defines for kernel-space
+# rtlinux_INCLUDES .. additional include directories and defines for RT-Linux
+# OMIT_KERNEL_PASSES  if defined, all kernel passes are omited
+#
+# LINUX_DIR        .. location of Linux kernel sources
+# RTL_DIR          .. location of RT-Linux sources
+# CFLAGS           .. C compiler flags
+# CXXFLAGS         .. C++ compiler flags
+# CPPFLAGS        .. C preprocessor flags
+# LDFLAGS         .. linker flags for programs linking
+# LOCAL_CONFIG_H   .. name of local config.h file generated from values #OMK@config_h
+#                     of options defined in the current directory
+# config_include_HEADERS .. names of global config files (possibly
+#                     with subdirectories)
+# xxx_DEFINES      .. list of config directives to be included in
+#                     config header file of the name <somedir>/xxx.h
+# DOXYGEN          .. if non-empty, generated headers includes Doxygen's @file
+#                    command, so it is possible to document config
+#                    variables.
+# QT_SUBDIRS       .. subdirectories where to build QT applications using qmake #OMK@qt
+# QTDIR                   .. where QT resides
+OMK_RULES_TYPE=linux                                         #OMK@__type
+                                                             #OMK@base
+# We need to ensure definition of sources directory first
+ifndef SOURCES_DIR
+# Only shell built-in pwd understands -L
+SOURCES_DIR := $(shell ( pwd -L ) )
+endif
+
+# If we are not called by OMK leaf Makefile...
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(abspath $(dir $(filter %Makefile.rules,$(MAKEFILE_LIST))))
+endif
+
+# OUTPUT_DIR is the place where _compiled, _build and possible other
+# files/directories are created. By default is the same as
+# $(MAKERULES_DIR).
+ifndef OUTPUT_DIR
+OUTPUT_DIR := $(MAKERULES_DIR)
+endif
+
+.PHONY: all default check-make-ver omkize
+
+ifdef W
+  ifeq ("$(origin W)", "command line")
+    OMK_WHOLE_TREE:=$(W)
+  endif
+endif
+ifndef OMK_WHOLE_TREE
+  OMK_WHOLE_TREE:=0
+endif
+
+ifneq ($(OMK_WHOLE_TREE),1)
+all: check-make-ver default
+       @echo "Compilation finished"
+else
+# Run make in the top-level directory
+all:
+       @$(MAKE) -C $(MAKERULES_DIR) OMK_SERIALIZE_INCLUDED=n SOURCES_DIR=$(MAKERULES_DIR) RELATIVE_DIR="" $(MAKECMDGOALS) W=0
+endif
+
+ifdef OMK_TESTSROOT
+# Usage: $(call canttest,<error message>)
+define canttest
+       ( echo "$(1)" > $(OUTPUT_DIR)/_canttest; echo "$(1)"; exit 1 )
+endef
+else
+define canttest
+       echo "$(1)"
+endef
+endif
+
+#=========================
+# Include the config file
+
+# FIXME: I think CONFIG_FILE_OK variable is useless. We have three
+# config files and it is not clearly defined to which file is this
+# variable related.
+ifneq ($(CONFIG_FILE_OK),y)
+ifndef CONFIG_FILE
+CONFIG_FILE      := $(OUTPUT_DIR)/config.omk
+endif
+ifneq ($(wildcard $(CONFIG_FILE)-default),)
+-include $(CONFIG_FILE)-default
+else
+ifneq ($(MAKECMDGOALS),default-config)
+$(warning Please, run "make default-config" first)
+endif
+endif
+
+-include $(OUTPUT_DIR)/config.target
+
+ifneq ($(wildcard $(CONFIG_FILE)),)
+-include $(CONFIG_FILE)
+CONFIG_FILE_OK = y
+endif
+endif #$(CONFIG_FILE_OK)
+
+
+CONFIG_FILES ?= $(wildcard $(CONFIG_FILE)-default) $(wildcard $(OUTPUT_DIR)/config.target) $(wildcard $(CONFIG_FILE))
+
+
+export SOURCES_DIR MAKERULES_DIR RELATIVE_DIR
+export CONFIG_FILE CONFIG_FILES OMK_SERIALIZE_INCLUDED OMK_VERBOSE OMK_SILENT
+# OMK_SERIALIZE_INCLUDED has to be exported to submakes because passes
+# must to be serialized only in the toplevel make.
+
+ifndef RELATIVE_DIR
+RELATIVE_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+endif
+#$(warning  === RELATIVE_DIR = "$(RELATIVE_DIR)" ===)
+override RELATIVE_DIR := $(RELATIVE_DIR:/%=%)
+override RELATIVE_DIR := $(RELATIVE_DIR:\\%=%)
+#$(warning  RELATIVE_DIR = "$(RELATIVE_DIR)")
+override BACK2TOP_DIR := $(shell echo $(RELATIVE_DIR)/ | sed -e 's_//_/_g' -e 's_/\./_/_g' -e 's_^\./__g'  -e 's_\([^/][^/]*\)_.._g' -e 's_/$$__')
+#$(warning  BACK2TOP_DIR = "$(BACK2TOP_DIR)")
+
+#$(warning SOURCES_DIR = "$(SOURCES_DIR)")
+#$(warning MAKERULES_DIR = "$(OUTPUT_DIR)")
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+
+# We have to use RELATIVE_PREFIX because of mingw
+override RELATIVE_PREFIX := $(RELATIVE_DIR)/
+override RELATIVE_PREFIX := $(RELATIVE_PREFIX:/%=%)
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+# Define srcdir for Automake compatibility
+srcdir = $(SOURCES_DIR)
+
+# Defines for quiet compilation
+ifdef V
+  ifeq ("$(origin V)", "command line")
+    OMK_VERBOSE = $(V)
+  endif
+endif
+ifndef OMK_VERBOSE
+  OMK_VERBOSE = 0
+endif
+ifneq ($(OMK_VERBOSE),0)
+  Q =
+else
+  Q = @
+endif
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+  QUIET_CMD_ECHO = true
+  OMK_SILENT = 1
+else
+  QUIET_CMD_ECHO = echo
+endif
+
+MAKEFILE_OMK=Makefile.omk
+# All subdirectories (even linked ones) containing Makefile.omk
+# Usage in Makefile.omk: SUBDIRS = $(ALL_OMK_SUBDIRS)
+ALL_OMK_SUBDIRS = $(patsubst %/$(MAKEFILE_OMK),%,$(patsubst $(SOURCES_DIR)/%,%,$(wildcard $(SOURCES_DIR)/*/$(MAKEFILE_OMK))))
+
+# ===================================================================
+# We have set up all important variables, so we can check and include
+# real OCERA style Makefile.omk now
+ifndef OMK_INCLUDED
+include $(SOURCES_DIR)/$(MAKEFILE_OMK)
+ifeq ($(AUTOMATIC_SUBDIRS),y)
+SUBDIRS?=$(ALL_OMK_SUBDIRS)
+endif
+OMK_INCLUDED := 1
+endif
+
+check-make-ver:
+       @GOOD_MAKE_VERSION=`echo $(MAKE_VERSION) | sed -n -e 's/^[4-9]\..*\|^3\.9[0-9].*\|^3\.8[1-9].*/y/p'` ; \
+       if [ x$$GOOD_MAKE_VERSION != xy ] ; then \
+               echo "Your make program version is too old and does not support OMK system." ; \
+               echo "Please update to make program 3.81beta1 or newer." ; exit 1 ; \
+       fi
+
+distclean dist-clean:
+       @$(QUIET_CMD_ECHO) "  RM      $(COMPILED_DIR_NAME) $(BUILD_DIR_NAME)"
+       @rm -fr $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)  $(OUTPUT_DIR)/$(BUILD_DIR_NAME)
+
+# Common OMK templates
+# ====================
+
+# Syntax: $(call mkdir,<dir name>)
+define mkdir_def
+       [ -d $(1) ] || mkdir -p $(1) || exit 1
+endef
+
+ifneq ($(OMK_VERBOSE),2)
+NO_PRINT_DIRECTORY := --no-print-directory
+endif
+
+ifeq ($(USE_LEAF_MAKEFILES),n)
+export USE_LEAF_MAKEFILES
+SUBDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+SOURCESDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+else
+SUBDIR_MAKEFILE=$(SOURCES_DIR)/$(3)/Makefile
+SOURCESDIR_MAKEFILE=$(SOURCES_DIR)/Makefile
+endif
+
+pass = $(strip $(1))
+
+# Call a pass in a subdirectory
+# Usage: $(call omk_pass_subdir_template,<pass name>,<build dir>,<subdir>)
+define omk_pass_subdir_template
+.PHONY: $(pass)-$(3)-subdir
+$(pass)-submakes: $(pass)-$(3)-subdir
+$(pass)-$(3)-subdir:
+       @$(call mkdir_def,$(2)/$(3))
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(3) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(3) -C $(2)/$(3) \
+               -f $(SUBDIR_MAKEFILE) $(pass)-submakes
+# In subdirectories we can call submakes directly since passes are
+# already searialized on the toplevel make.
+endef
+
+ifdef OMK_TESTSROOT
+check-target = $(1:%=%-check)
+endif
+
+# Call a pass in a subdirectory
+# Usage: $(call extra_rules_subdir_template,<subdir>)
+define extra_rules_subdir_template
+extra-rules-subdirs: extra-rules-$(1)
+extra-rules-$(1):
+       +@$(MAKE) OMK_SERIALIZE_INCLUDED=n MAKERULES_DIR=$(SOURCES_DIR)/$(1) OUTPUT_DIR=$(OUTPUT_DIR) \
+               SOURCES_DIR=$(SOURCES_DIR)/$(1) RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) -C $(SOURCES_DIR)/$(1)
+endef
+
+.PHONY: extra-rules-subdirs
+extra-rules-subdirs:
+
+$(foreach subdir,$(EXTRA_RULES_SUBDIRS),$(eval $(call extra_rules_subdir_template,$(subdir))))
+
+# Usage: $(call omk_pass_template,<pass name>,<build dir>,[<local make flags>],[<local enable condition>])
+define omk_pass_template
+.PHONY: $(pass) $(pass)-local $(pass)-check $(pass)-submakes
+$(foreach subdir,$(SUBDIRS),$(eval $(call omk_pass_subdir_template,$(pass),$(2),$(subdir))))
+$(pass):
+# Submakes have to be called this way and not as dependecies for pass
+# serialization to work
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_DIR) \
+               -f $(SOURCESDIR_MAKEFILE) $(pass)-submakes
+$(pass)-submakes:
+       @true                   # Do not emit "nothing to be done" messages
+
+ifneq ($(4)$($(pass)_HOOKS),)
+$(pass)-submakes: $(pass)-this-dir
+$(pass)-this-dir: $(foreach subdir,$(SUBDIRS),$(pass)-$(subdir)-subdir)
+       +@echo "make[omk]: $(pass) in $(RELATIVE_DIR)"
+       @$(call mkdir_def,$(2))
+       +@$(MAKE) $(NO_PRINT_DIRECTORY) SOURCES_DIR=$(SOURCES_DIR) RELATIVE_DIR=$(RELATIVE_DIR) -C $(2) \
+               -f $(SOURCESDIR_MAKEFILE) $(3) $(check-target) $(1:%=%-local)
+$(pass)-local: $($(pass)_HOOKS)
+endif
+endef
+
+# =======================
+# DEFAULT CONFIG PASS
+
+default-config:
+       @echo "# Start of OMK config file" > "$(CONFIG_FILE)-default"
+       @echo "# This file should not be altered manually" >> "$(CONFIG_FILE)-default"
+       @echo "# Overrides should be stored in file $(notdir $(CONFIG_FILE))" >> "$(CONFIG_FILE)-default"
+       @echo >> "$(CONFIG_FILE)-default"
+       @$(MAKE) $(NO_PRINT_DIRECTORY) -C $(OUTPUT_DIR) \
+               RELATIVE_DIR="" SOURCES_DIR=$(OUTPUT_DIR) \
+               -f $(OUTPUT_DIR)/Makefile default-config-pass
+
+$(eval $(call omk_pass_template,default-config-pass,$$(LOCAL_BUILD_DIR),,always))
+
+default-config-pass-local:
+#      @echo Default config for $(RELATIVE_DIR)
+       @echo "# Config for $(RELATIVE_DIR)" >> "$(CONFIG_FILE)-default"
+       @$(foreach x, $(default_CONFIG), echo '$(x)' | \
+               sed -e 's/^[^=]*=x$$/#\0/' >> "$(CONFIG_FILE)-default" ; )
+
+
+omkize:
+       $(Q)if ! grep -q MAKERULES_DIR Makefile; then \
+          echo "Makefile is not OMK leaf makefile!" >&2; exit 1; \
+       fi
+       $(Q)for i in `find -L . -name Makefile.omk` ; do \
+          d=`dirname $${i}`; \
+          if ! test -f "$${d}/Makefile.rules" && ( ! test -f "$${d}/Makefile" || ! cmp --silent Makefile "$${d}/Makefile" ); then \
+             rm -f "$${d}/Makefile"; \
+             cp -v Makefile "$${d}/Makefile"; \
+          fi \
+       done
+ifeq ($(OMK_VERBOSE),1)                                      #OMK@include
+CPHEADER_FLAGS += -v
+LNHEADER_FLAGS += -v
+endif
+
+ifneq ($(LN_HEADERS),y)
+define cp_cmd
+( echo "  CP      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; cp $(CPHEADER_FLAGS) $(1) $(2) )
+endef
+else
+define cp_cmd
+( echo "  LN      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; [ -f $(1) ] && ln -sf $(LNHEADER_FLAGS) $(1) $(2) )
+endef
+endif
+
+# TODO: Check modification date of changed header files. If it is
+# newer that in source dir, show a warning.
+
+# Syntax: $(call include-pass-template,<include dir>,<keyword>)
+define include-pass-template
+include-pass-local: include-pass-local-$(2)
+include-pass-local-$(2): $$($(2)_GEN_HEADERS) $$(foreach f,$$(renamed_$(2)_GEN_HEADERS),$$(shell echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'))
+       @$$(foreach f, $$($(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(notdir $$(f)) \
+          || $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; )
+       @$$(foreach f, $$($(2)_GEN_HEADERS), cmp --quiet $$(f) $(1)/$$(notdir $$(f)) \
+          || $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; ) # FIXME: Use correct build dir, then document it
+       @$$(foreach f, $$(nobase_$(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(f) \
+          || ( mkdir -p $(1)/$$(dir $$(f)) && $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(f)) ) || exit 1 ; )
+       @$$(foreach f, $$(renamed_$(2)_HEADERS), \
+          srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+          cmp --quiet $$(SOURCES_DIR)/$$$${srcfname} $(1)/$$$${destfname} \
+          || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(SOURCES_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+       @$$(foreach f, $$(renamed_$(2)_GEN_HEADERS), \
+          srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+          cmp --quiet $$$${srcfname} $(1)/$$$${destfname} \
+          || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+endef
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@linux
+# Hack to check RT-Linux rules
+#LINUX_DIR := /home/cvs/ocera/ocera-build/kernel/linux
+#RTL_DIR := /home/cvs/ocera/ocera-build/kernel/rtlinux
+#CONFIG_RTLINUX = y
+#OCERA_DIR := $(shell ( cd -L $(OUTPUT_DIR)/../../.. ; pwd -L ) )
+
+-include $(OUTPUT_DIR)/OCERA_TOP_DIR
+
+BUILD_DIR_NAME = _build
+COMPILED_DIR_NAME = _compiled
+ifndef GROUP_DIR_NAME
+GROUP_DIR_NAME = nogroup
+endif
+
+ifdef OCERA_DIR
+ifeq ($(wildcard $(OCERA_DIR)/ocera.mk),)
+$(warning "ocera.mk" file does not exist. Adapt Makefile.rules for standalone compilation)
+$(warning (comment out definition of OCERA_DIR line and optionally select RTL_DIR) )
+$(error or go to the ocera/ directory and do 'make' to generate the "ocera.mk" file first, please)
+endif
+include $(OCERA_DIR)/ocera.mk
+KERN_INCLUDE_DIR := $(OCERA_KERNEL_INCLUDES_DIR)
+KERN_LIB_DIR     := $(OCERA_KERNEL_LIBRARIES_DIR)
+KERN_MODULES_DIR := $(OCERA_MODULES_DIR)
+KERN_BUILD_DIR   := $(BUILD_DIR)/kern/$(GROUP_DIR_NAME)
+KERN_MODPOST_DIR := $(BUILD_DIR)/kern-modpost
+USER_INCLUDE_DIR := $(OCERA_USER_INCLUDES_DIR)
+USER_LIB_DIR     := $(OCERA_USER_LIBRARIES_DIR)
+USER_UTILS_DIR   := $(TARGET_DIR)/usr/bin
+USER_TESTS_DIR   := $(TARGET_DIR)/usr/bin
+USER_BIN_DIR     := $(TARGET_DIR)/usr/bin
+USER_BUILD_DIR   := $(BUILD_DIR)/user/$(GROUP_DIR_NAME)
+#LINUX_DIR        := $(OCERA_DIR)/kernel/linux
+#RTL_DIR          := $(OCERA_DIR)/kernel/rtlinux
+#CONFIG_FILE      := $(OCERA_DIR)/emdebsys/.config 
+ifneq ($(wildcard $(CONFIG_FILE)),)
+CONFIG_FILE_OK = y
+endif
+else # OCERA_DIR
+KERN_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include-kern
+KERN_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib-kern
+KERN_MODULES_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/modules
+KERN_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern
+KERN_MODPOST_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern-modpost
+USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include
+USER_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib
+USER_UTILS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils
+USER_TESTS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests
+USER_BIN_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin
+USER_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user
+
+ifndef LINUX_VERSION
+LINUX_VERSION=$(shell uname -r)
+endif
+ifndef LINUX_DIR
+LINUX_DIR=/lib/modules/$(LINUX_VERSION)/build
+endif
+endif # OCERA_DIR
+
+ifeq ($(BUILD_OS),)
+  # Check for target
+  ifeq ($(OS),Windows_NT)
+    BUILD_OS := win32
+  else
+    BUILD_OS := $(shell uname | tr '[A-Z]' '[a-z]' )
+    #$(warning BUILD_OS=$(BUILD_OS))
+  endif
+endif
+
+ifeq ($(TARGET_OS),)
+  TARGET_OS := $(BUILD_OS)
+endif
+
+LOCAL_BUILD_DIR  = $(USER_OBJS_DIR)
+
+# Assign default values to CFLAGS variable. If the variable is defined
+# earlier (i.g. in config.omk), it is not overriden here.
+CFLAGS ?= -O2 -Wall
+CXXFLAGS ?= -O2 -Wall
+
+
+CPPFLAGS  += -I $(USER_INCLUDE_DIR)
+
+LOADLIBES += -L$(USER_LIB_DIR) 
+
+LOADLIBES += $(lib_LOADLIBES:%=-l%)
+
+LIB_CPPFLAGS += $(CPPFLAGS)
+LIB_CFLAGS   += $(CFLAGS)
+
+ifeq ($(TARGET_OS),win32)
+  SOLIB_EXT = dll
+else
+  SOLIB_EXT = so
+  SOLIB_PICFLAGS += -fpic
+endif
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR)
+KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR)
+
+.PHONY: dep subdirs clean clean-custom cleandepend check-dir
+
+# Some support to serialize some targets for parallel make
+ifneq ($(OMK_SERIALIZE_INCLUDED),y)
+include-pass: check-dir
+library-pass: include-pass
+binary-pass: library-pass
+kernel-lib-pass: include-pass
+kernel-mod-pass: kernel-lib-pass
+kernel-modpost-pass: kernel-mod-pass
+kernel-pass: kernel-mod-pass kernel-modpost-pass
+
+override OMK_SERIALIZE_INCLUDED = y
+MAKEOVERRIDES := $(filter-out OMK_SERIALIZE_INCLUDED=n,$(MAKEOVERRIDES))
+endif
+
+# Checks for OMK tester
+ifdef OMK_TESTSROOT
+default-config-pass-check include-pass-check:
+library-pass-check binary-pass-check:
+       @[ -x "$(shell which $(CC))" ] || $(call canttest,Cannot find compiler: $(CC))
+endif
+
+#=====================================================================
+# User-space rules and templates to compile programs, libraries etc.
+
+ifdef USER_RULE_TEMPLATES
+
+USER_SOURCES2OBJS = .o/.c .o/.cc .o/.cxx .o/.S .o/.o
+
+USER_SOURCES2OBJSLO = .lo/.c .lo/.cc .lo/.cxx .lo/.S .lo/.lo
+
+#%.lo: %.c
+#      $(CC) -o $@ $(LCFLAGS) -c $<
+
+c_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+cc_o_COMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+S_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASFLAGS) -DOMK_FOR_USER
+
+idl_COMPILE = $(IDL_COMPILER)
+
+# Check GCC version for user build
+ifndef CC_MAJOR_VERSION
+CC_MAJOR_VERSION := $(shell $(CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(CC_MAJOR_VERSION),2)
+CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+
+# Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_c_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CC      $$@"
+       $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_cc_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CXX     $$@"
+       $(Q) if $$(cc_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_S_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  AS      $$@"
+       $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call CMETRIC_o_h_template,<object_file>,<target_header>)
+define CMETRIC_o_h_template
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CMETRIC $$@"
+       $(Q)if [ -n `dirname $$@` ] ; then \
+             if [ ! -e `dirname $$@` ] ; then \
+               mkdir -p `dirname $$@` ; fi ; fi
+       $(Q)echo >$$@ '/* Automatically generated from $$< */'
+       $(Q)echo >>$$@ '/* Conditionals to control compilation */'
+       $(Q)set -o pipefail ; $(NM) $$< \
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2cond_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@
+       $(Q)echo >>$$@ '/* Defines from the values defined to symbols */'
+       $(Q)set -o pipefail ; $(NM) $$< \
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2def_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@
+endef
+
+
+
+define COMPILE_idl_template
+$(2).c $(2)-stubs.c $(2)-skels.c $(2)-common.c $(2).h: $(1)
+       @$(QUIET_CMD_ECHO) "  IDL     $$@"
+       $(Q) $$(idl_COMPILE) $(1)
+endef
+
+
+# Syntax: $(call PROGRAM_template,<dir>,<executable-name>,<executable-suffix>,<linker-sript>)
+# FIXME: ???????? asi je tu blbej komentar
+define PROGRAM_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(2)/$(1)$(3): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q) $$(if $$(filter %.cc,$$($(1)_SOURCES:%.cxx=%.cc)),$$(CXX),$$(CC)) \
+         $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(LDFLAGS) -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$@
+       @echo "$(2)/$(1)$(3): \\" >$(USER_OBJS_DIR)/$(1).exe.d
+       @sed -n -e 's|^LOAD \(.*\)$$$$|  \1  \&|p' $(USER_OBJS_DIR)/$(1).exe.map|tr '&' '\134'  >>$(USER_OBJS_DIR)/$(1).exe.d
+       @echo >>$(USER_OBJS_DIR)/$(1).exe.d
+endef
+
+
+# Syntax: $(call LIBRARY_template,<library-name>)
+define LIBRARY_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR      $$@"
+       $(Q) $(AR) rcs $$@ $$^
+endef
+
+
+# Syntax: $(call SOLIB_template,<library-name>)
+define SOLIB_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+SOLIB_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJSLO),
+$(1)_OBJSLO += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJSLO := $$(sort $$($(1)_OBJSLO:%/=%))
+
+SOLIB_OBJS  += $$($(1)_OBJSLO)
+SOLIB_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).$(SOLIB_EXT): $$($(1)_OBJSLO)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q) $(CC) --shared -Xlinker -soname=lib$(1).$(SOLIB_EXT) -o $$@ $$^ $$(LOADLIBES) $$($(1)_LIBS:%=-l%)
+endef
+
+
+
+library-pass-local: $(addprefix $(USER_INCLUDE_DIR)/,$(cmetric_include_HEADERS)) \
+                   $(lib_LIBRARIES:%=$(USER_LIB_DIR)/lib%.a) $(shared_LIBRARIES:%=$(USER_LIB_DIR)/lib%.$(SOLIB_EXT))
+
+binary-pass-local: $(bin_PROGRAMS:%=$(USER_BIN_DIR)/%$(EXE_SUFFIX)) $(utils_PROGRAMS:%=$(USER_UTILS_DIR)/%$(EXE_SUFFIX)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%$(EXE_SUFFIX))
+
+# Special rules for CMETRIC generated headers
+
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call COMPILE_c_o_template,\
+               $(SOURCES_DIR)/$($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES),\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),)))
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call CMETRIC_o_h_template,\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),\
+               $(addprefix $(USER_INCLUDE_DIR)/,$(cmetrh)))))
+
+GEN_HEADERS+=$(cmetric_include_HEADERS:%=$(USER_INCLUDE_DIR)/%)
+
+GEN_HEADERS+=$(filter %.h,$(USER_IDLS:%.idl=%.h))
+
+# Generate rules for compilation of programs and libraries
+
+$(foreach prog,$(utils_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_UTILS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(test_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(bin_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR),$(EXE_SUFFIX))))
+
+$(foreach lib,$(lib_LIBRARIES),$(eval $(call LIBRARY_template,$(lib))))
+
+$(foreach lib,$(shared_LIBRARIES),$(eval $(call SOLIB_template,$(lib))))
+
+-include $(USER_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+# Kernel-space rules and templates to compile modules, libraries etc.
+
+ifdef KERN_RULE_TEMPLATES
+
+$(KERN_LIB_DIR)/kernel.mk: $(LINUX_DIR)/.config $(MAKERULES_DIR)/kernelcfg2mk
+       @$(QUIET_CMD_ECHO) "  KCFG2MK $$@"
+       $(Q) $(MAKERULES_DIR)/kernelcfg2mk $(LINUX_DIR) $(KERN_LIB_DIR)
+
+ifeq ($(CONFIG_RTLINUX),y)
+include $(RTL_DIR)/rtl.mk
+
+KERN_CC = $(CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+INCLUDES := -I $(KERN_INCLUDE_DIR) $(INCLUDE) $(rtlinux_INCLUDES) $(kernel_INCLUDES)
+#-DEXPORT_NO_SYMBOLS
+c_o_kern_COMPILE = $(KERN_CC) -idirafter $(kern_GCCLIB_DIR)/include $(INCLUDES)  $(CFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(CXX) $(INCLUDES) $(CXXFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := .o
+KERN_ARCH = $(ARCH)
+KERN_LD = $(LD)
+KERN_AR = $(AR)
+
+else # CONFIG_RTLINUX
+
+include $(KERN_LIB_DIR)/kernel.mk
+
+ifeq ($(LINUX_SRC),)
+LINUX_SRC = $(LINUX_DIR)
+endif
+kernel_INCLUDES += -I $(LINUX_DIR) -idirafter $(LINUX_SRC)/include/linux
+
+ifdef LINUX_CC
+KERN_CC = $(LINUX_CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(LINUX_CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+else
+KERN_CC = echo KERN_CC not defined - compilation skipped
+endif
+c_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+S_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_AFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := $(LINUX_MODULE_EXT)
+KERN_LDFLAGS = $(LINUX_LDFLAGS)
+ifdef LINUX_ARCH
+KERN_ARCH = $(LINUX_ARCH)
+else
+KERN_ARCH = echo KERN_ARCH not defined - skipped
+endif
+ifdef LINUX_LD
+KERN_LD = $(LINUX_LD)
+else
+KERN_LD = echo KERN_LD  not defined - skipped
+endif
+ifneq ($(LINUX_AR),)
+KERN_AR = $(LINUX_AR)
+else
+KERN_AR = $(AR)
+endif
+ifeq ($(LINUX_QUOTE_MODNAME),y)
+KERN_MQ=\"
+KERN_KBUILD_MODNAME=-D"KBUILD_MODNAME=((THIS_MODULE)?(THIS_MODULE)->name:NULL)"
+endif
+endif # CONFIG_RTLINUX
+
+KERN_LOADLIBES += -L$(KERN_LIB_DIR) 
+
+KERN_LOADLIBES += $(rtlinux_LOADLIBES:%=-l%)
+KERN_LOADLIBES += $(kernel_LOADLIBES:%=-l%)
+
+
+
+# Check GCC version for kernel part of build
+ifndef kern_CC_MAJOR_VERSION
+kern_CC_MAJOR_VERSION := $(shell $(KERN_CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(kern_CC_MAJOR_VERSION),2)
+kern_CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+kern_CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+ifeq ($(KERN_EXE_SUFFIX),.ko)
+ifeq ($(wildcard $(LINUX_DIR)/scripts/mod/modpost),)
+KERN_MODPOST = $(LINUX_DIR)/scripts/modpost
+else
+KERN_MODPOST = $(LINUX_DIR)/scripts/mod/modpost
+endif
+KERN_MODULES_LINK_DIR = $(KERN_MODPOST_DIR)
+KERN_LINK_SUFFIX = .o
+else
+KERN_MODULES_LINK_DIR = $(KERN_MODULES_DIR)
+KERN_LINK_SUFFIX = $(KERN_EXE_SUFFIX)
+endif
+
+define COMPILE_c_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CC [K]  $$@"
+       $(Q) if $$(c_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_cc_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CXX [K] $$@"
+       $(Q) if $$(cc_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_S_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  AS [K]  $$@"
+       $(Q) if $$(S_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define MODULE_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+# this is hack to build "__this_module" structure for 2.6.x kernels
+# modpost is used for that purpose now
+
+#$(1).mod.c:
+#      echo  "\
+#      #include <linux/version.h>@\
+#      #include <linux/module.h>@\
+#      #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5))@\
+#      #include <linux/vermagic.h>@\
+#      #include <linux/compiler.h>@\
+#      @\
+#      MODULE_INFO(vermagic, VERMAGIC_STRING);@\
+#      @\
+#      #undef unix@\
+#      struct module __this_module@\
+#      __attribute__((section(\".gnu.linkonce.this_module\"))) = {@\
+#       .name = __stringify(KBUILD_MODNAME),@\
+#       .init = init_module,@\
+#      #ifdef CONFIG_MODULE_UNLOAD@\
+#       .exit = cleanup_module,@\
+#      #endif@\
+#      };@\
+#      #endif@\
+#      " | tr @ \\n >$$@ 
+
+
+#$(eval $(call COMPILE_c_o_kern_template,$(1).mod.c,$(1).mod.o,-DKBUILD_MODNAME=$(1)))
+
+$(2)/$(1)$(KERN_LINK_SUFFIX): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LD [K]  $$@"
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) -r $$($(1)_OBJS) -L$$(kern_GCCLIB_DIR) $$($(1)_LIBS:%=-l%) $$(KERN_LOADLIBES) -Map $(KERN_OBJS_DIR)/$(1).mod.map -o $$@
+       @echo "$(2)/$(1)$(KERN_LINK_SUFFIX): \\" >$(KERN_OBJS_DIR)/$(1).mod.d
+       @sed -n -e 's/^LOAD \(.*\)$$$$/  \1  \\/p' $(KERN_OBJS_DIR)/$(1).mod.map  >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @echo >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @if [ "$(KERN_EXE_SUFFIX)" = ".ko" ] ; then \
+         echo $(1) >>$(KERN_MODPOST_DIR)/module-changes ; \
+         echo $(1) >>$(KERN_MODPOST_DIR)/$(1).mod.stamp ; \
+       fi
+
+endef
+
+
+
+define LIBRARY_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+$(KERN_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR [K]  $$@"
+       $(Q) $(KERN_AR) rcs $$@ $$^
+endef
+
+
+ifdef LINUX_DIR
+
+kernel-lib-pass-local: $(kernel_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+kernel-mod-pass-local: $(kernel_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+$(foreach module,$(kernel_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(kernel_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+
+ifeq ($(CONFIG_RTLINUX),y)
+
+kernel-mod-pass-local: $(rtlinux_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+kernel-lib-pass-local: $(rtlinux_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+$(foreach module,$(rtlinux_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(rtlinux_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+ifeq ($(KERN_MODPOST_PASS),y)
+
+MODULES_LIST :=        $(wildcard *.mod.stamp)
+MODULES_LIST := $(MODULES_LIST:%.mod.stamp=%)
+
+define MODPOST_kern_template
+$(2) : $(1)$(KERN_LINK_SUFFIX) $(1).mod.c
+       @$(QUIET_CMD_ECHO) "  LD [M]  $$@"
+       $(Q) $$(cc_o_kern_COMPILE) -D"KBUILD_BASENAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -D"KBUILD_MODNAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -o $(1).mod.o -c $(1).mod.c
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) $(1)$(KERN_LINK_SUFFIX) $(1).mod.o -r -o $$@
+endef
+
+kernel-modpost-versions: $(wildcard $(LINUX_DIR)/Module.symvers)
+       @$(QUIET_CMD_ECHO) "  MODPOST    $(KERN_MODPOST_DIR)"
+       @echo  >$(KERN_MODPOST_DIR)/modpost-running
+       @rm -f $(KERN_MODPOST_DIR)/module-changes
+       $(Q) $(KERN_MODPOST) $(MODULES_LIST:%=%$(KERN_LINK_SUFFIX)) $(^:%=-i %)
+
+$(MODULES_LIST:%=%.mod.c) : kernel-modpost-versions
+
+kernel-modpost-pass-local: $(MODULES_LIST:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX))
+       @rm -f $(KERN_MODPOST_DIR)/modpost-running
+
+$(foreach module,$(MODULES_LIST),$(eval $(call MODPOST_kern_template,$(module),$(module:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX)))))
+
+endif
+
+-include $(KERN_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+
+# Kernel requires its own set of configuration header-files
+ifneq ($(kernel_LIBRARIES)$(rtlinux_LIBRARIES)$(kernel_MODULES)$(rtlinux_MODULES)$(kernel_HEADERS)$(rtlinux_HEADERS)$(kernel_HEADERS)$(rtlinux_HEADERS)$(nobase_kernel_HEADERS)$(nobase_rtlinux_HEADERS)$(renamed_kernel_HEADERS)$(renamed_rtlinux_HEADERS),)
+KERN_CONFIG_HEADERS_REQUIRED = y
+endif
+
+$(eval $(call omk_pass_template, kernel-lib-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_LIBRARIES)$(rtlinux_LIBRARIES)))
+$(eval $(call omk_pass_template, kernel-mod-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_MODULES)$(rtlinux_MODULES)))
+
+kernel-modpost-pass:
+       +@if [ -e "$(KERN_MODPOST_DIR)/module-changes" -o -e "$(KERN_MODPOST_DIR)/modpost-running" ] ; \
+       then \
+           $(MAKE) --no-print-directory -C $(KERN_MODPOST_DIR) \
+              -f $(SOURCES_DIR)/Makefile KERN_RULE_TEMPLATES=y KERN_MODPOST_PASS=y $(@:%=%-local) ; \
+       fi
+
+$(eval $(call omk_pass_template, library-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(lib_LIBRARIES)$(shared_LIBRARIES)))
+$(eval $(call omk_pass_template, binary-pass, $(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(bin_PROGRAMS)$(utils_PROGRAMS)$(test_PROGRAMS)))
+
+$(eval $(call omk_pass_template,clean,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,install,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,include-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,always))
+
+check-dir::
+       @$(call mkdir_def,$(USER_BUILD_DIR))
+       @$(call mkdir_def,$(KERN_BUILD_DIR))
+       @$(call mkdir_def,$(USER_INCLUDE_DIR))
+       @$(call mkdir_def,$(KERN_INCLUDE_DIR))
+       @$(call mkdir_def,$(USER_LIB_DIR))
+       @$(call mkdir_def,$(KERN_LIB_DIR))
+       @$(call mkdir_def,$(USER_BIN_DIR))
+       @$(call mkdir_def,$(USER_UTILS_DIR))
+       @$(call mkdir_def,$(USER_TESTS_DIR))
+       @$(call mkdir_def,$(KERN_MODULES_DIR))
+       @$(call mkdir_def,$(KERN_MODPOST_DIR))
+
+install-local:                 # TODO
+
+$(eval $(call include-pass-template,$(USER_INCLUDE_DIR),include))
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),kernel))
+ifeq ($(CONFIG_RTLINUX),y)
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),rtlinux))
+endif
+
+
+ifdef USER_RULE_TEMPLATES
+
+# User-space static libraries and applications object files
+
+USER_SOURCES := $(sort $(USER_SOURCES))
+
+USER_GEN_SOURCES := $(sort $(USER_GEN_SOURCES))
+
+#$(warning USER_SOURCES = $(USER_SOURCES))
+
+$(foreach src,$(filter %.c,$(USER_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+
+$(foreach src,$(filter %.c,$(USER_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.o),)))
+
+# User-space shared libraries object files
+
+SOLIB_SOURCES := $(sort $(SOLIB_SOURCES))
+
+SOLIB_GEN_SOURCES := $(sort $(SOLIB_GEN_SOURCES))
+
+#$(warning SOLIB_SOURCES = $(SOLIB_SOURCES))
+#$(warning SOLIB_GEN_SOURCES = $(SOLIB_GEN_SOURCES))
+
+$(foreach src,$(filter %.c,$(SOLIB_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cc,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cxx,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.S,$(SOLIB_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.c,$(SOLIB_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+# IDL compilation
+
+USER_IDLS := $(sort $(USER_IDLS))
+
+$(foreach src,$(filter %.idl,$(USER_IDLS)),$(eval $(call COMPILE_idl_template,$(SOURCES_DIR)/$(src),$(src:%.idl=%))))
+
+endif
+
+ifdef KERN_RULE_TEMPLATES
+
+KERN_SOURCES := $(sort $(KERN_SOURCES))
+
+#$(warning KERN_SOURCES = $(KERN_SOURCES))
+
+$(foreach src,$(filter %.c,$(KERN_SOURCES)),$(eval $(call COMPILE_c_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+endif
+
+clean-local: clean-custom
+       @echo Cleaning in $(KERN_OBJS_DIR) and $(USER_OBJS_DIR)
+       @rm -f $(KERN_OBJS_DIR)/*.o $(USER_OBJS_DIR)/*.[och] $(USER_OBJS_DIR)/*.lo\
+              $(KERN_OBJS_DIR)/*.d $(USER_OBJS_DIR)/*.d \
+              $(KERN_OBJS_DIR)/*.map $(USER_OBJS_DIR)/*.map \
+              $(KERN_OBJS_DIR)/*.mod.c \
+              $(kernel_MODULES:%=$(KERN_MODPOST_DIR)/%.*) \
+              $(LOCAL_CONFIG_H:%=$(KERN_OBJS_DIR)/%) \
+              $(LOCAL_CONFIG_H:%=$(USER_OBJS_DIR)/%)
+       @if [ -e $(KERN_LIB_DIR)/kernel.mk ] ; then \
+           touch -t 200001010101 $(KERN_LIB_DIR)/kernel.mk ; \
+       fi
+
+include-pass-submakes: extra-rules-subdirs
+
+# We must go to EXTRA_RULES_SUBDIRS beofre going to any other
+# directory, since the executables compiled in EXTRA_RULES_SUBDIRS
+# might be needed there.
+include-pass-this-dir $(foreach subdir,$(SUBDIRS),include-pass-$(subdir)-subdir): extra-rules-subdirs
+
+default: include-pass library-pass binary-pass
+ifndef OMIT_KERNEL_PASSES
+# Also make kernel passes if not disabled
+default: kernel-lib-pass kernel-pass
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@config_h
+# Syntax: $(call BUILD_CONFIG_H_template,<stamp_dir>,<header_file_path>,<list_of_options_to_export>,<header_barrier>)
+define BUILD_CONFIG_H_template
+
+$(addprefix $(1)/,$(notdir $(addsuffix .stamp,$(2)))) : $(CONFIG_FILES)
+       @$(QUIET_CMD_ECHO) "  CONFGEN $$(@:%.stamp=%)"
+       @if [ ! -d `dirname $(2).tmp` ] ; then \
+               mkdir -p `dirname $(2).tmp` ; fi
+       @echo "/* Automatically generated from */" > "$(2).tmp"
+       @echo "/* config files: $$(^:$(OUTPUT_DIR)/%=%) */" >> "$(2).tmp"
+       $(if $(DOXYGEN),@echo "/** @file */" >> "$(2).tmp")
+       @echo "#ifndef $(4)" >> "$(2).tmp"
+       @echo "#define $(4)" >> "$(2).tmp"
+       @( $(foreach x, $(shell echo '$($(3))' | tr 'x\t ' 'x\n\n' | sed -e 's/^\([^ =]*\)\(=[^ ]\+\|\)$$/\1/' ), \
+               echo '$(x).$($(x))' ; ) echo ; ) | \
+               sed -e '/^[^.]*\.n$$$$/d' -e '/^[^.]*\.$$$$/d' -e 's/^\([^.]*\)\.[ym]$$$$/\1.1/' | \
+               sed -n -e 's/^\([^.]*\)\.\(.*\)$$$$/#define \1 \2/p' \
+                 >> "$(2).tmp"
+       @echo "#endif /*$(4)*/" >> "$(2).tmp"
+       @touch "$$@"
+       @if cmp --quiet "$(2).tmp" "$(2)" ; then rm "$(2).tmp"; \
+       else mv "$(2).tmp" "$(2)" ; \
+       echo "Updated configuration $(2)" ; fi
+
+endef
+
+ifdef LOCAL_CONFIG_H
+
+# This must be declared after the default cflags are assigned!
+# Override is used to override command line assignemnt.
+override CFLAGS += -I.
+$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(USER_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+
+endif
+
+# Special rules for configuration exported headers
+
+#FIXME: The directory for headers should not be specified here.
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(addprefix $(USER_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+config_h_stamp_files = $(addprefix $(USER_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(config_h_stamp_files)
+
+ifneq ($(KERN_CONFIG_HEADERS_REQUIRED),)
+
+ifdef LOCAL_CONFIG_H
+$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(KERN_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+endif
+
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(addprefix $(KERN_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+kern_config_h_stamp_files = $(addprefix $(KERN_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(kern_config_h_stamp_files)
+
+endif
+
+clean-local: clean-local-config-h
+
+clean-local-config-h:
+       @$(foreach confh,$(config_h_stamp_files) $(kern_config_h_stamp_files),\
+           if [ -e $(confh) ] ; then rm $(confh) ; fi ; \
+       )
+
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@qt
+ifneq ($(QT_SUBDIRS),)
+
+.PHONY: qt-subpass clean-qt distclean-qt
+
+# Usage: $(call qt_makefile_template,<qt-subdir>)
+define qt_makefile_template
+$(SOURCES_DIR)/$(1)/Makefile: $(wildcard $(SOURCES_DIR)/$(1)/*.pro)
+       cd $(SOURCES_DIR)/$(1); $(QTDIR:%=%/bin/)qmake TOP_DIR=$(OUTPUT_DIR) \
+            RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) $(QTDIR:%=QTDIR=%) CC=$(CC) \
+            CXX=$(CXX) LIBS+="-L$(USER_LIB_DIR)" INCLUDEPATH+="$(USER_INCLUDE_DIR)"
+endef
+$(foreach dir,$(QT_SUBDIRS), $(eval $(call qt_makefile_template,$(dir))))
+
+qt-subpass: $(foreach dir,$(QT_SUBDIRS), $(SOURCES_DIR)/$(dir)/Makefile)
+       $(foreach dir,$(QT_SUBDIRS),\
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile || exit 1 ;)
+
+# Hook to binary pass
+binary-pass-submakes: qt-subpass
+
+# Hook to clean pass
+clean-local: clean-qt
+clean-qt:
+       +@$(foreach dir, $(QT_SUBDIRS), \
+               $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+               @$(QUIET_CMD_ECHO) "  CLEAN   $(dir)"; \
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile clean|| exit 1 ;))
+
+
+# Hook to distclean
+distclean: distclean-qt
+
+# TODO: Add distclean-qt-pass to handle QT_SUBDIRS in the whole
+# tree. This way we only distclean toplevel subdirs.
+distclean-qt:
+       +@$(foreach dir, $(QT_SUBDIRS), \
+               $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+               @$(QUIET_CMD_ECHO) "  DISTCLEAN $(dir)"; \
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile distclean|| exit 1 ;))
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@sources-list
+# Rules that creates the list of files which are used during
+# compilation. The list reflects conditional compilation depending on
+# config.omk and other variables.
+
+SOURCES_LIST_FN=sources.txt
+ifndef SOURCES_LIST
+SOURCES_LIST_DIR:=$(RELATIVE_DIR)
+SOURCES_LIST:=$(OUTPUT_DIR)/$(SOURCES_LIST_DIR)/$(SOURCES_LIST_FN)
+SOURCES_LIST_D := $(LOCAL_BUILD_DIR)/$(SOURCES_LIST_FN).d
+export SOURCES_LIST SOURCES_LIST_DIR SOURCES_LIST_D
+endif
+
+ifeq ($(MAKECMDGOALS),sources-list)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),TAGS)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),tags)
+NEED_SOURCES_LIST=y
+endif
+
+ifeq ($(NEED_SOURCES_LIST),y) # avoid execution of find command bellow if it is not useful
+.PHONY: sources-list
+sources-list: $(SOURCES_LIST)
+
+$(SOURCES_LIST): $(CONFIG_FILES) $(shell find -name $(MAKEFILE_OMK))
+       @echo -n "" > "$(SOURCES_LIST).tmp"
+       @echo -n "" > "$(SOURCES_LIST_D).tmp"
+       @$(MAKE) --no-print-directory sources-list-pass
+       @echo "# Automatically generated list of files in '$(RELATIVE_DIR)' that are used during OMK compilation" > "$(SOURCES_LIST).tmp2"
+       @cat "$(SOURCES_LIST).tmp"|sort|uniq >> "$(SOURCES_LIST).tmp2"
+       @rm "$(SOURCES_LIST).tmp"
+       @mv "$(SOURCES_LIST).tmp2" "$(SOURCES_LIST)"
+       @echo "$(SOURCES_LIST): \\" > "$(SOURCES_LIST_D).tmp2"
+       @cat "$(SOURCES_LIST_D).tmp"|grep -v "$(SOURCES_LIST_D).tmp"|sort|uniq|\
+               sed -e 's/$$/\\/' >> "$(SOURCES_LIST_D).tmp2"
+       @rm "$(SOURCES_LIST_D).tmp"
+       @mv "$(SOURCES_LIST_D).tmp2" "$(SOURCES_LIST_D)"
+endif
+
+$(eval $(call omk_pass_template,sources-list-pass,$$(LOCAL_BUILD_DIR),,always))
+
+sources-list-pass-local:
+       @$(foreach m,$(MAKEFILE_LIST),echo '  $(m)' >> "$(SOURCES_LIST_D).tmp";)
+       @$(foreach h,$(include_HEADERS) $(nobase_include_HEADERS) $(kernel_HEADERS),\
+         echo "$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%)/$(h)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach ch,$(config_include_HEADERS), \
+         echo "$(USER_INCLUDE_DIR:$(OUTPUT_DIR)/$(addsuffix /,$(SOURCES_LIST_DIR))%=%)/$(ch)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach h,$(renamed_include_HEADERS),echo '$(h)'|sed -e 's/\(.*\)->.*/$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%)\1/' >> "$(SOURCES_LIST).tmp";)
+       @$(foreach bin,$(lib_LIBRARIES) $(shared_LIBRARIES) $(bin_PROGRAMS) $(test_PROGRAMS) $(utils_PROGRAMS) \
+         $(kernel_LIBRARIES) $(rtlinux_LIBRARIES) $(kernel_MODULES),\
+         $(foreach src,$(filter-out %.o,$($(bin)_SOURCES)),echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(src)" >> "$(SOURCES_LIST).tmp";))
+
+############ TAGS ###########
+
+ifeq ($(MAKECMDGOALS),TAGS)
+ETAGS=etags
+TAGS_CMD = $(ETAGS)
+TAGS: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+ifeq ($(MAKECMDGOALS),tags) 
+CTAGS=ctags -N
+TAGS_CMD = $(CTAGS)
+tags: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+export TAGS_CMD
+
+ifeq ($(MAKECMDGOALS),do-tags)
+.PHONY: do-tags
+do-tags: $(shell sed -e '/^\#/d' $(SOURCES_LIST))
+       @$(QUIET_CMD_ECHO) "  TAGS    $(SOURCES_LIST_FN)"
+       $(Q)$(TAGS_CMD) $^
+endif
+
+############ CSCOPE ###########
+
+cscope: $(SOURCES_LIST)
+       @$(QUIET_CMD_ECHO) "  CSCOPE  < $(SOURCES_LIST_FN)"
+       $(Q)sed -e '/^#/d' $(SOURCES_LIST)|cscope -b -i-
+#FIXME: see doc to -i in cscope(1)
+
+# Local Variables:
+# mode:makefile
+# End:
diff --git a/src/forb/forb-idl/ORBit-idl-2.0.pc.in b/src/forb/forb-idl/ORBit-idl-2.0.pc.in
new file mode 100644 (file)
index 0000000..219e7d2
--- /dev/null
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+backendsdir=@libdir@/orbit-2.0/idl-backends
+
+Name: ORBit-idl-2.0
+Description: ORBit-2.0 IDL Compiler Backend Interface
+Version: @ORBIT_VERSION@
+Requires: libIDL-2.0
+Libs: 
+Cflags: -I${includedir}/orbit-2.0/orbit-idl
diff --git a/src/forb/forb-idl/config.h b/src/forb/forb-idl/config.h
new file mode 100644 (file)
index 0000000..922426b
--- /dev/null
@@ -0,0 +1,202 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define if HTTP connections are available */
+/* #undef ENABLE_HTTP */
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Define to 1 if you have the `basename' function. */
+#define HAVE_BASENAME 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Define to 1 if you have the <endian.h> header file. */
+#define HAVE_ENDIAN_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if getaddrinfo() is available */
+#define HAVE_GETADDRINFO 1
+
+/* Define if getnameinfo() is available */
+#define HAVE_GETNAMEINFO 1
+
+/* Define if inet_pton() is available */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+/* #undef HAVE_LIBNSL */
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+/* #undef HAVE_LIBRESOLV */
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define to 1 if you have the <linux/socket.h> header file. */
+#define HAVE_LINUX_SOCKET_H 1
+
+/* Define to 1 if you have the <machine/endian.h> header file. */
+/* #undef HAVE_MACHINE_ENDIAN_H */
+
+/* Define to 1 if you have the <machine/types.h> header file. */
+/* #undef HAVE_MACHINE_TYPES_H */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define to 1 if you have the `poll' function. */
+#define HAVE_POLL 1
+
+/* Define to 1 if you have the <resolv.h> header file. */
+#define HAVE_RESOLV_H 1
+
+/* Define if sockaddr has sa_len member */
+/* #undef HAVE_SOCKADDR_SA_LEN */
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define to 1 if you have the <sys/endian.h> header file. */
+/* #undef HAVE_SYS_ENDIAN_H */
+
+/* Define to 1 if you have the <sys/isa_defs.h> header file. */
+/* #undef HAVE_SYS_ISA_DEFS_H */
+
+/* Define to 1 if you have the <sys/machine.h> header file. */
+/* #undef HAVE_SYS_MACHINE_H */
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#define HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+/* #undef HAVE_SYS_SOCKIO_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H 1
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+/* #undef HAVE_SYS_UTIME_H */
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define to 1 if you have the <wcstr.h> header file. */
+/* #undef HAVE_WCSTR_H */
+
+/* Define to 1 if you have the <wctype.h> header file. */
+#define HAVE_WCTYPE_H 1
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* defined if purify is enabled */
+/* #undef ORBIT_PURIFY */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "http://bugzilla.gnome.org/enter_bug.cgi?product=ORBit2"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "ORBit2"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "ORBit2 2.14.13"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "ORBit2"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.14.13"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel and VAX). */
+#if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+#elif ! defined __LITTLE_ENDIAN__
+/* # undef WORDS_BIGENDIAN */
+#endif
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define socklen_t to be of type size_t */
+/* #undef socklen_t */
diff --git a/src/forb/forb-idl/forb-idl-backend.c b/src/forb/forb-idl/forb-idl-backend.c
new file mode 100644 (file)
index 0000000..ecd3730
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * orbit-idl-backend.c:
+ *
+ * Copyright (C) 2002 Sun Microsystems, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ * Authors:
+ *     Mark McLoughlin <mark@skynet.ie>
+ */
+
+#include "config.h"
+
+#include "forb-idl-backend.h"
+#include "forb-idl2.h"
+
+#include <glib.h>
+#include <gmodule.h>
+
+#if 0
+static GSList *
+prepend_from_env_var (GSList     *paths,
+                     const char *env_var)
+{
+       char  *val;
+       char **strv;
+       int    i;
+
+       if (!(val = getenv ("GNOME2_PATH")))
+               return paths;
+
+       strv = g_strsplit (val, ";", -1);
+       for (i = 0; strv [i]; i++)
+               paths = g_slist_prepend (
+                               paths, g_strconcat (strv [i], "/lib/forb-2.0/idl-backends", NULL));
+
+       g_strfreev (strv);
+
+       return paths;
+}
+
+static ForbIDLBackendFunc
+load_language_backend (const char *path,
+                      const char *language)
+{
+       ForbIDLBackendFunc  retval = NULL;
+       GModule             *module;
+       char                *modname;
+       char                *modpath;
+
+       modname = g_strconcat ("forb-idl-backend-", language, NULL);
+       modpath = g_module_build_path (path, modname);
+       g_free (modname);
+
+       if (!(module = g_module_open (modpath, G_MODULE_BIND_LAZY))) {
+               g_free (modpath);
+               return NULL;
+       }
+
+       if (!g_module_symbol (module, "forb_idl_backend_func", (gpointer *) &retval))
+               g_warning ("backend %s has no \"forb_idl_backend_func\" defined", modpath);
+
+       g_free (modpath);
+
+       return retval;
+}
+
+gboolean
+forb_idl_backend_output (OIDL_Run_Info *rinfo,
+                         IDL_tree       tree)
+{
+       ForbIDLBackendFunc     func = NULL;
+       ForbIDLBackendContext  context;
+       GSList                 *paths = NULL;
+       GSList                 *l;
+
+       paths = prepend_from_env_var (paths, "GNOME2_PATH");
+       paths = prepend_from_env_var (paths, "FORB_BACKENDS_PATH");
+
+       paths = g_slist_prepend (paths, g_strdup (FORB_BACKENDS_DIR));
+
+       if (rinfo->backend_directory)
+               paths = g_slist_prepend (paths, g_strdup (rinfo->backend_directory));
+
+       for (l = paths; l; l = l->next) {
+               func = load_language_backend (l->data, rinfo->output_language);
+
+               g_free (l->data);
+
+               if (func)
+                       break;
+       }
+
+       g_slist_free (paths);
+
+       if (!func) {
+               g_warning("idl-compiler backend not found.");
+               return FALSE;
+       }
+
+       context.tree      = tree;
+       context.filename  = rinfo->input_filename;
+       context.do_stubs  = (rinfo->enabled_passes & OUTPUT_STUBS ? 1 : 0);
+       context.do_skels  = (rinfo->enabled_passes & OUTPUT_SKELS ? 1 : 0);
+       context.do_common = (rinfo->enabled_passes & OUTPUT_COMMON ? 1 : 0);
+
+       return func (&context);
+}
+#endif
diff --git a/src/forb/forb-idl/forb-idl-backend.h b/src/forb/forb-idl/forb-idl-backend.h
new file mode 100644 (file)
index 0000000..4460e94
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * forb-idl-backend.h:
+ *
+ * Copyright (C) 2002 Sun Microsystems, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ * Authors:
+ *     Mark McLoughlin <mark@skynet.ie>
+ */
+
+#ifndef __FORB_IDL_BACKEND_H__
+#define __FORB_IDL_BACKEND_H__
+
+#include <glib.h>
+#include <libIDL/IDL.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+       IDL_tree  tree;
+       char     *filename;
+
+       guint     do_stubs  : 1;
+       guint     do_skels  : 1;
+       guint     do_common : 1;
+} ForbIDLBackendContext;
+
+/* Define a function with this signature and named "forb_idl_backend_func"
+ * in the module.
+ *
+ * The module should be named libforb-idl-backend-$(language).so. $(language)
+ * is defined with the --lang idl-compiler command line option.
+ *
+ * Modules are searched for in the following order:
+ *   1. The directory specified by the --backenddir option.
+ *   2. %(prefix)/lib/forb-2.0/idl-backends/, where $(prefix) is the prefix
+ *      Forb2 was installed in.
+ *   3. For each $(path) in the $FORB_BACKENDS_PATH environment variable,
+ *      the module is searched for in $(path)/lib/forb-2.0/idl-backends/
+ *   4. For each $(path) in the $GNOME2_PATH environment variable,
+ *      the module is searched for in $(path)/lib/forb-2.0/idl-backends/
+ */
+
+typedef gboolean (*ForbIDLBackendFunc) (ForbIDLBackendContext *context);
+
+G_END_DECLS
+
+#endif
diff --git a/src/forb/forb-idl/forb-idl-c-backend.c b/src/forb/forb-idl/forb-idl-c-backend.c
new file mode 100644 (file)
index 0000000..9c574c1
--- /dev/null
@@ -0,0 +1,166 @@
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <glib/gstdio.h>
+
+static FILE *out_for_pass(const char *input_filename, int pass, 
+                         OIDL_Run_Info *rinfo);
+
+gboolean
+forb_idl_output_c (IDL_tree       tree,
+                   OIDL_Run_Info *rinfo)
+{
+  int i;
+  char *ctmp;
+  OIDL_C_Info ci;
+
+  ci.base_name = g_path_get_basename(rinfo->input_filename);
+  ctmp = strrchr(ci.base_name, '.');
+  g_assert(ctmp);
+  *ctmp = '\0';
+
+  ci.c_base_name = g_strdup(ci.base_name);
+  if(!isalpha((guchar)ci.c_base_name[0]))
+    ci.c_base_name[0] = '_';
+  for(i = 0; ci.c_base_name[i]; i++) {
+    if(!isalnum((guchar)ci.c_base_name[i])) ci.c_base_name[i] = '_';
+  }
+
+  ci.ext_dcls = g_string_new(NULL);
+
+  ci.do_impl_hack = 1;
+  ci.do_skel_defs = rinfo->do_skel_defs;
+  for(i = 0; i < OUTPUT_NUM_PASSES; i++) {
+    if( (1 << i) & rinfo->enabled_passes) {
+      ci.fh = out_for_pass(rinfo->input_filename, 1 << i, rinfo);
+      
+      switch(1 << i) {
+      case OUTPUT_STUBS:
+       forb_idl_output_c_stubs(tree, rinfo, &ci);
+       break;
+      case OUTPUT_SKELS:
+       forb_idl_output_c_skeletons(tree, rinfo, &ci);
+       break;
+      case OUTPUT_COMMON:
+       forb_idl_output_c_common(tree, rinfo, &ci);
+       break;
+      case OUTPUT_HEADERS:
+       forb_idl_output_c_headers(tree, rinfo, &ci);
+       break;
+      case OUTPUT_SKELIMPL:
+       forb_idl_output_c_skelimpl(tree, rinfo, &ci);
+       break;
+      case OUTPUT_IMODULE:
+       forb_idl_output_c_imodule(tree, rinfo, &ci);
+       break;
+      case OUTPUT_DEPS:
+       forb_idl_output_c_deps(tree, rinfo, &ci);
+       break;
+      }
+      fclose(ci.fh);
+    }
+  }
+  g_string_free(ci.ext_dcls,TRUE);
+
+  return TRUE;
+}
+
+char *
+forb_idl_c_filename_for_pass (const char *input_filename, 
+                               int pass)
+{
+       char *filename;
+       char *basename;
+       char *dot;
+       const char *tack_on = NULL;
+  
+       basename = g_path_get_basename (input_filename);
+       dot = strrchr (basename, '.');
+       if (dot != NULL)
+               *dot = '\0';
+
+       switch (pass) {
+       case OUTPUT_STUBS:
+               tack_on = "-stubs.c";
+               break;
+       case OUTPUT_SKELS:
+               tack_on = "-skels.c";
+               break;
+       case OUTPUT_COMMON:
+               tack_on = "-common.c";
+               break;
+       case OUTPUT_HEADERS:
+               tack_on = ".h";
+               break;
+       case OUTPUT_SKELIMPL:
+               tack_on = "-skelimpl.c";
+               break;
+       case OUTPUT_IMODULE:
+               tack_on = "-imodule.c";
+               break;
+       default:
+               g_error("Unknown output pass");
+               break;
+       }
+
+       filename = g_strconcat (basename, tack_on, NULL);
+       g_free (basename);
+
+       return filename;
+}
+
+static FILE *
+out_for_pass (const char    *input_filename,
+             int            pass,
+             OIDL_Run_Info *rinfo)
+{
+       FILE *fp;
+       char *output_filename;
+       gchar *output_full_path = NULL;
+
+
+        if ((strlen(rinfo->output_directory)) && (!g_file_test (rinfo->output_directory, G_FILE_TEST_IS_DIR))) {
+               g_error ("ouput directory '%s' does not exist",
+                        rinfo->output_directory);
+               return NULL;
+       }
+       
+       if (pass == OUTPUT_DEPS) {
+               if (!g_file_test (".deps", G_FILE_TEST_IS_DIR)) {
+                       if (g_mkdir (".deps", 0775) < 0) {
+                               g_warning ("failed to create '.deps' directory '%s'",
+                                          g_strerror (errno));
+                               return NULL;
+                       }
+               }
+               
+               if (rinfo->deps_file)
+                       fp =  g_fopen (rinfo->deps_file, "w");
+               else
+                       fp = NULL;
+
+               if (fp == NULL) 
+                       g_warning ("failed to open '%s': %s\n",
+                                  rinfo->deps_file, g_strerror (errno));
+               
+       } else {
+               output_filename = forb_idl_c_filename_for_pass (input_filename, pass);
+               output_full_path = g_build_path (G_DIR_SEPARATOR_S, rinfo->output_directory, output_filename, NULL);
+               g_free (output_filename);
+
+               fp = g_fopen (output_full_path, "w+");
+               if (fp == NULL)
+                       g_error ("failed to fopen '%s': %s\n", output_full_path, g_strerror(errno));
+
+               g_free (output_full_path);
+       }
+
+       return fp;
+}
diff --git a/src/forb/forb-idl/forb-idl-c-backend.h b/src/forb/forb-idl/forb-idl-c-backend.h
new file mode 100644 (file)
index 0000000..b1a3870
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef FORB_IDL_C_BACKEND_H
+#define FORB_IDL_C_BACKEND_H
+
+#include "forb-idl2.h"
+#include <stdbool.h>
+
+#define OIDL_C_WARNING "/*\n * This file was generated by forb-idl - DO NOT EDIT!\n */\n\n"
+
+typedef struct {
+       char     *base_name;
+       char     *c_base_name;
+       FILE     *fh;
+       GString  *ext_dcls;
+       gboolean  do_impl_hack;
+       gboolean  do_skel_defs;
+} OIDL_C_Info;
+
+enum forb_ser {
+  DESERIALIZE,
+  SERIALIZE
+};
+
+void
+forb_cbe_write_ser_var(FILE *of, IDL_tree ts, IDL_tree name, bool use_name,
+                      char *var_prefix, enum forb_ser serialization);
+
+
+gboolean  forb_idl_output_c       (IDL_tree       tree,
+                                   OIDL_Run_Info *rinfo);
+void  forb_idl_output_c_headers   (IDL_tree       tree,
+                                   OIDL_Run_Info *rinfo,
+                                   OIDL_C_Info   *ci);
+void  forb_idl_output_c_stubs     (IDL_tree       tree,
+                                   OIDL_Run_Info *rinfo,
+                                   OIDL_C_Info   *ci);
+void  forb_idl_output_c_skeletons (IDL_tree       tree,
+                                   OIDL_Run_Info *rinfo,
+                                   OIDL_C_Info   *ci);
+void  forb_idl_output_c_common    (IDL_tree       tree,
+                                   OIDL_Run_Info *rinfo,
+                                   OIDL_C_Info   *ci);
+void  forb_idl_output_c_skelimpl  (IDL_tree       tree,
+                                   OIDL_Run_Info *rinfo,
+                                   OIDL_C_Info   *ci);
+void  forb_idl_output_c_imodule   (IDL_tree       tree,
+                                   OIDL_Run_Info *rinfo,
+                                   OIDL_C_Info   *ci);
+void  forb_idl_output_c_deps      (IDL_tree       tree,
+                                   OIDL_Run_Info *rinfo,
+                                   OIDL_C_Info   *ci);
+
+void forb_output_typecode (OIDL_C_Info *ci, IDL_tree ts);
+
+char *forb_idl_c_filename_for_pass (const char *input_filename, int pass);
+
+/* utils */
+char    *forb_cbe_get_typespec_str     (IDL_tree    tree);
+void     forb_cbe_write_typespec       (FILE       *of,
+                                        IDL_tree    tree);
+void     forb_cbe_write_param_typespec (FILE       *of,
+                                        IDL_tree    tree);
+void     forb_cbe_op_write_proto       (FILE       *of,
+                                        IDL_tree    op,
+                                        const char *nom_prefix,
+                                        gboolean    for_epv);
+IDL_tree forb_cbe_get_typespec         (IDL_tree    tree);
+void     forb_cbe_write_const          (FILE       *of,
+                                        IDL_tree    tree);
+gboolean forb_cbe_type_is_fixed_length (IDL_tree    ts);
+gboolean forb_cbe_type_is_builtin      (IDL_tree    tree);
+void     forb_cbe_id_define_hack       (FILE       *fh,
+                                        const char *def_prefix,
+                                        const char *def_name,
+                                        const char *def_value);
+void     forb_cbe_id_cond_hack         (FILE       *fh,
+                                        const char *def_prefix,
+                                        const char *def_name,
+                                        const char *def_value);
+char    *forb_cbe_get_typecode_name    (IDL_tree    tree);
+void     forb_cbe_flatten_args         (IDL_tree    tree,
+                                        FILE       *of,
+                                        const char *name);
+void     forb_cbe_unflatten_args       (IDL_tree    tree,
+                                        FILE       *of,
+                                        const char *name);
+#endif
diff --git a/src/forb/forb-idl/forb-idl-c-common.c b/src/forb/forb-idl/forb-idl-c-common.c
new file mode 100644 (file)
index 0000000..b2e4ec7
--- /dev/null
@@ -0,0 +1,896 @@
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+
+typedef struct {
+       IDL_tree tree;
+       GSList  *methods; /* IDLN_OP_DCLs */
+} Interface;
+
+typedef struct {
+       FILE     *of;
+       IDL_tree cur_node; /* Current Interface */
+       char     *cur_id;
+       guint    parents;
+} CCSmallInterfaceTraverseInfo;
+
+/* TypeCodes */
+
+/* static void cc_output_typecodes (IDL_tree     tree, */
+/*                              OIDL_C_Info *ci); */
+
+/* static void */
+/* cc_typecode_prep_sequence (IDL_tree     tree, */
+/*                        OIDL_C_Info *ci) */
+/* { */
+/*     IDL_tree  seq_type; */
+/*     IDL_tree  fake_seq_type = NULL; */
+/*     char     *type_str; */
+/*     char     *seq_type_str; */
+
+/*     seq_type = forb_cbe_get_typespec (IDL_TYPE_SEQUENCE (tree).simple_type_spec); */
+
+/*     if (IDL_NODE_TYPE (seq_type) != IDLN_INTERFACE) */
+/*             seq_type_str = forb_cbe_get_typespec_str (seq_type); */
+/*     else { */
+/*             seq_type_str = g_strdup ("CORBA_Object"); */
+/*             fake_seq_type = IDL_type_object_new (); */
+/*     } */
+
+/*     type_str = forb_cbe_get_typespec_str (IDL_TYPE_SEQUENCE (tree).simple_type_spec); */
+
+/*     if (strcmp (type_str, seq_type_str)) { */
+/*             IDL_tree fake_seq; */
+
+/*             fake_seq = IDL_type_sequence_new ( */
+/*                             fake_seq_type ? fake_seq_type : seq_type, */
+/*                             NULL); */
+/*             IDL_NODE_UP (fake_seq) = IDL_NODE_UP (tree); */
+
+/*             cc_output_typecodes (fake_seq, ci); */
+
+/*             IDL_TYPE_SEQUENCE (fake_seq).simple_type_spec = NULL; */
+/*             IDL_tree_free (fake_seq); */
+/*     } */
+
+/*     if (fake_seq_type) */
+/*             IDL_tree_free (fake_seq_type); */
+
+/*     g_free (type_str); */
+/*     g_free (seq_type_str); */
+/* } */
+/* static gboolean */
+/* cc_output_tc_walker (IDL_tree_func_data *tfd, */
+/*                  OIDL_C_Info        *ci) */
+/* { */
+/*     IDL_tree tree = tfd->tree; */
+
+/*     switch(IDL_NODE_TYPE (tree)) { */
+/*     case IDLN_CONST_DCL: */
+/*     case IDLN_ATTR_DCL: */
+/*     case IDLN_OP_DCL: */
+/*             return FALSE; /\* dont recurse into these *\/ */
+
+/*     case IDLN_TYPE_SEQUENCE: */
+/*             if (!tfd->step) { */
+/*                     cc_typecode_prep_sequence (tree, ci); */
+/*                     break; */
+/*             } */
+/*             /\* drop through *\/ */
+
+/*     case IDLN_INTERFACE: */
+/*     case IDLN_EXCEPT_DCL: */
+/*     case IDLN_TYPE_STRUCT: */
+/*     case IDLN_TYPE_UNION: */
+/*     case IDLN_TYPE_DCL: */
+/*     case IDLN_TYPE_ENUM: */
+/*     case IDLN_TYPE_FIXED: */
+/*             if (tfd->step) */
+/*                     forb_output_typecode (ci, tree); */
+/*             break; */
+/*     default: */
+/*             break; */
+/*     } */
+
+/*     return TRUE; /\* continue walking *\/ */
+/* } */
+
+/* static void */
+/* cc_output_typecodes (IDL_tree     tree, */
+/*                  OIDL_C_Info *ci) */
+/* { */
+/*     IDL_tree_walk2 (tree, NULL, IDL_WalkF_TypespecOnly, */
+/*                     (IDL_tree_func) cc_output_tc_walker, */
+/*                     (IDL_tree_func) cc_output_tc_walker, */
+/*                     ci); */
+/* } */
+
+/* serialization */
+
+static void
+cc_output_ser_struct(OIDL_C_Info *ci,
+                    IDL_tree     s)
+{
+       IDL_tree cur, curmem;
+       char *id;
+       id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_TYPE_STRUCT(s).ident), "_", 0);
+       
+       fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s *ptr)\n", id, id);
+       fprintf(ci->fh, "{\n");
+       for(cur = IDL_TYPE_STRUCT(s).member_list; cur; cur = IDL_LIST(cur).next) {
+               for(curmem = IDL_MEMBER(IDL_LIST(cur).data).dcls; curmem; curmem = IDL_LIST(curmem).next) {
+                       forb_cbe_write_ser_var(
+                               ci->fh,
+                               IDL_MEMBER(IDL_LIST(cur).data).type_spec,
+                               IDL_LIST(curmem).data,
+                               true,
+                               "ptr->",
+                               SERIALIZE);
+               }
+       }
+       
+       fprintf(ci->fh, "  return CORBA_TRUE;\n"
+                       "ser_exception:\n"
+                       "  return CORBA_FALSE;\n"
+                       "}\n\n");
+
+       fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s *ptr)\n", id, id);
+       fprintf(ci->fh, "{\n");
+       for(cur = IDL_TYPE_STRUCT(s).member_list; cur; cur = IDL_LIST(cur).next) {
+               for(curmem = IDL_MEMBER(IDL_LIST(cur).data).dcls; curmem; curmem = IDL_LIST(curmem).next) {
+                       forb_cbe_write_ser_var(
+                               ci->fh,
+                               IDL_MEMBER(IDL_LIST(cur).data).type_spec,
+                               IDL_LIST(curmem).data,
+                               true,
+                               "ptr->",
+                               DESERIALIZE);
+               }
+       }
+       
+       fprintf(ci->fh, "  return CORBA_TRUE;\n"
+                       "ser_exception:\n"
+                       "  return CORBA_FALSE;\n"
+                       "}\n\n");
+
+
+       g_free(id);
+}
+
+static void
+cc_output_ser_seqence(OIDL_C_Info *ci,
+                     IDL_tree     s)
+{
+        //IDL_tree cur, curmem;
+       char *id, *type;
+       IDL_tree tts;
+       gboolean fake_if;
+       id = forb_cbe_get_typespec_str(s);
+       type = forb_cbe_get_typespec_str(IDL_TYPE_SEQUENCE(s).simple_type_spec);
+/*{
+       CORBA_boolean r;                                                
+       int i;                                                  
+       r = CORBA_unsigned_long_serialize(codec, (val)->_length); 
+       for (i=0; i<(val)->_length && r; i++)                   
+               r = type ## _serialize(codec, &((val)->_buffer[i])); 
+}*/
+       tts = forb_cbe_get_typespec(IDL_TYPE_SEQUENCE(s).simple_type_spec);
+       fake_if = (IDL_NODE_TYPE(tts) == IDLN_INTERFACE);
+       if (fake_if) {
+               /* Header file already contains defines for CORBA_sequence_Object_[de]serialize */
+               return;
+       }
+
+       fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s *seq)\n", id, id);
+       fprintf(ci->fh, "{\n"
+                       "  int i;\n"
+                       "  CORBA_boolean ok;\n"
+                       "  ok = CORBA_unsigned_long_serialize(codec, &seq->_length);\n"
+                       "  for (i = 0; i<seq->_length && ok; i++)\n");
+       fprintf(ci->fh, "    ok = %s_serialize(codec, &(seq->_buffer[i]));\n", type);
+       
+       fprintf(ci->fh, "  return ok;\n"
+                       "}\n\n");
+
+       fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s *seq)\n", id, id);
+       fprintf(ci->fh, "{\n"
+                       "  CORBA_unsigned_long i;\n"
+                       "  CORBA_boolean ok;\n"
+                       "  ok = CORBA_unsigned_long_deserialize(codec, &i);\n"
+                       "  if (ok) {\n"
+                       "    ok = forb_sequence_alloc_buf(seq, i);\n"
+                       "    seq->_length = i;\n"
+                       "    CORBA_sequence_set_release(seq, CORBA_TRUE);\n"
+                       "  }\n"
+                       "  for (i = 0; i<seq->_length && ok; i++)\n");
+       fprintf(ci->fh, "    ok = %s_deserialize(codec, &(seq->_buffer[i]));\n", type);
+       
+       fprintf(ci->fh, "  return ok;\n"
+                       "}\n\n");
+
+       g_free(id);
+       g_free(type);
+}
+
+static void
+cc_output_ser_typedef_array(OIDL_C_Info *ci,
+                      IDL_tree     tree)
+{
+       IDL_tree cur;
+       char *id;
+       
+       for(cur = IDL_TYPE_DCL(tree).dcls; cur; cur = IDL_LIST(cur).next) {
+               if (IDL_NODE_TYPE(IDL_LIST(cur).data) == IDLN_TYPE_ARRAY) {
+                       id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_TYPE_ARRAY(IDL_LIST(cur).data).ident), "_", 0);
+                       fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s array)\n", id, id);
+                       fprintf(ci->fh, "{\n");
+                       forb_cbe_write_ser_var(
+                               ci->fh,
+                               IDL_TYPE_DCL(tree).type_spec,
+                               IDL_LIST(cur).data,
+                               false,
+                               "array",
+                               SERIALIZE);
+                       fprintf(ci->fh, "  return CORBA_TRUE;\n"
+                               "ser_exception:\n"
+                               "  return CORBA_FALSE;\n"
+                               "}\n\n");
+
+                       fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s array)\n", id, id);
+                       fprintf(ci->fh, "{\n");
+                       forb_cbe_write_ser_var(
+                               ci->fh,
+                               IDL_TYPE_DCL(tree).type_spec,
+                               IDL_LIST(cur).data,
+                               false,
+                               "array",
+                               DESERIALIZE);
+                       fprintf(ci->fh, "  return CORBA_TRUE;\n"
+                               "ser_exception:\n"
+                               "  return CORBA_FALSE;\n"
+                               "}\n\n");
+                       g_free(id);
+               }
+       }
+}
+
+void
+forb_output_serialization (OIDL_C_Info *ci,
+                          IDL_tree     node)
+{
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_DCL:
+               cc_output_ser_typedef_array(ci, node);
+               break;
+       case IDLN_TYPE_STRUCT:
+               cc_output_ser_struct(ci, node);
+               break;
+       case IDLN_TYPE_UNION:
+       case IDLN_TYPE_ENUM:
+       case IDLN_EXCEPT_DCL:
+       case IDLN_INTERFACE:
+               break;
+       case IDLN_TYPE_SEQUENCE:
+               cc_output_ser_seqence(ci, node);
+               break;
+       default:
+               g_error ("You can't produce a serialization for a %s", 
+                        IDL_tree_type_names[IDL_NODE_TYPE (node)]);
+       }
+
+/*     tci.ts            = node; */
+/*     tci.structname    = forb_generate_tcstruct_name (node); */
+/*     tci.substructname = NULL; */
+/*     tci.array_gen_ctr = 0; */
+
+/*     cbe_tc_generate (ci, &tci); */
+
+/*     g_free (tci.structname); */
+}
+
+static gboolean
+cc_output_serialization_walker (IDL_tree_func_data *tfd,
+                               OIDL_C_Info        *ci)
+{
+       IDL_tree tree = tfd->tree;
+
+       switch(IDL_NODE_TYPE (tree)) {
+       case IDLN_CONST_DCL:
+       case IDLN_ATTR_DCL:
+       case IDLN_OP_DCL:
+               return FALSE; /* dont recurse into these */
+
+       case IDLN_TYPE_SEQUENCE:
+/*             if (!tfd->step) { */
+/*                     cc_typecode_prep_sequence (tree, ci); */
+/*                     break; */
+/*             } */
+               /* drop through */
+
+       case IDLN_INTERFACE:
+       case IDLN_EXCEPT_DCL:
+       case IDLN_TYPE_STRUCT:
+       case IDLN_TYPE_UNION:
+       case IDLN_TYPE_DCL:
+       case IDLN_TYPE_ENUM:
+       case IDLN_TYPE_FIXED:
+               if (tfd->step)
+                       forb_output_serialization (ci, tree);
+               break;
+       case IDLN_SRCFILE:
+               if (!IDL_SRCFILE(tree).isTop) {
+                       return FALSE;
+               }
+               break;
+       default:
+               break;
+       }
+
+       return TRUE; /* continue walking */
+}
+
+static void
+cc_output_serialization (IDL_tree     tree,
+                        OIDL_C_Info *ci)
+{
+       IDL_tree_walk2 (tree, NULL, IDL_WalkF_TypespecOnly,
+                       (IDL_tree_func) cc_output_serialization_walker,
+                       (IDL_tree_func) cc_output_serialization_walker,
+                       ci);
+}
+
+
+
+/* class ids */
+
+/* static void */
+/* cc_output_class_id (IDL_tree       tree, */
+/*                        OIDL_Run_Info *rinfo, */
+/*                        OIDL_C_Info   *ci) */
+/* { */
+/*     char *iface_id; */
+
+/*     iface_id = IDL_ns_ident_to_qstring ( */
+/*             IDL_IDENT_TO_NS (IDL_INTERFACE (tree).ident), "_", 0); */
+
+/*     fprintf (ci->fh, "\n#ifndef FORB_IDL_C_IMODULE_%s\n",ci->c_base_name); */
+/*     fprintf (ci->fh, "CORBA_unsigned_long %s__classid = 0;\n", iface_id); */
+/*     fprintf (ci->fh, "#endif\n"); */
+
+/*     g_free (iface_id); */
+/* } */
+
+/* static void */
+/* cc_output_class_ids (IDL_tree       tree, */
+/*                  OIDL_Run_Info *rinfo, */
+/*                  OIDL_C_Info   *ci) */
+/* { */
+/*     if (!tree || (tree->declspec & IDLF_DECLSPEC_PIDL)) */
+/*             return; */
+
+/*     switch (IDL_NODE_TYPE (tree)) { */
+/*     case IDLN_MODULE: */
+/*             cc_output_class_ids (IDL_MODULE (tree).definition_list, rinfo, ci); */
+/*             break; */
+/*     case IDLN_LIST: { */
+/*             IDL_tree node; */
+
+/*             for (node = tree; node; node = IDL_LIST (node).next) */
+/*                     cc_output_class_ids (IDL_LIST (node).data, rinfo, ci); */
+/*             break; */
+/*             } */
+/*     case IDLN_INTERFACE: */
+/*             cc_output_class_id (tree, rinfo, ci); */
+/*             break; */
+/*     default: */
+/*             break; */
+/*     } */
+/* } */
+
+/* IInterfaces */
+
+/* static void */
+/* cc_output_iargs (FILE *of, const char *method, IDL_tree tree) */
+/* { */
+/*     IDL_tree sub; */
+/*     int      arg_count = 0; */
+
+/*     /\* Build a list of IArgs *\/ */
+/*     for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; */
+/*          sub = IDL_LIST (sub).next) { */
+/*             IDL_tree parm; */
+/*             char    *tc; */
+
+/*             if (!arg_count) */
+/*                     fprintf (of, "static Forb_IArg %s__arginfo [] = {\n", method); */
+
+/*             parm = IDL_LIST(sub).data; */
+
+/*             fprintf (of, "\t{ "); */
+
+/*             /\* TypeCode tc *\/ */
+/*             tc = forb_cbe_get_typecode_name ( */
+/*                     IDL_PARAM_DCL (parm).param_type_spec); */
+/*             if (!tc) { */
+/*                     g_warning ("Can't get typecode"); */
+/*                     tc = g_strdup ("NULL /\* no typecode *\/"); */
+/*             } */
+/*             fprintf (of, "%s, ", tc); */
+
+/*             /\* IArgFlag flags *\/ */
+/*             switch (IDL_PARAM_DCL (parm).attr) { */
+/*             case IDL_PARAM_IN: */
+/*                     fprintf (of, " Forb_I_ARG_IN "); */
+/*                     break; */
+/*             case IDL_PARAM_OUT: */
+/*                     fprintf (of, " Forb_I_ARG_OUT "); */
+/*                     break; */
+/*             case IDL_PARAM_INOUT: */
+/*                     fprintf (of, " Forb_I_ARG_INOUT "); */
+/*                     break; */
+/*             } */
+
+/*             if (forb_cbe_type_is_fixed_length ( */
+/*                     IDL_PARAM_DCL (parm).param_type_spec)) */
+/*                     fprintf (of, "| Forb_I_COMMON_FIXED_SIZE"); */
+
+/*             else if (IDL_PARAM_DCL(parm).attr == IDL_PARAM_OUT) { */
+
+/*                     IDL_tree ts = forb_cbe_get_typespec ( */
+/*                             IDL_PARAM_DCL (parm).param_type_spec); */
+
+/*                     switch(IDL_NODE_TYPE (ts)) { */
+/*                     case IDLN_TYPE_STRUCT: */
+/*                     case IDLN_TYPE_UNION: */
+/*                     case IDLN_TYPE_ARRAY: */
+/* /\*                         fprintf (of, "| FORB_I_ARG_FIXED");*\/ */
+/*                             break; */
+/*                     default: */
+/*                             break; */
+/*                     }; */
+/*             } */
+
+/*             fprintf (of, ", "); */
+
+/*             /\* string name *\/ */
+/*             fprintf (of, "(char *)\"%s\"", IDL_IDENT (IDL_PARAM_DCL ( */
+/*                     IDL_LIST (sub).data).simple_declarator).str); */
+
+/*             fprintf (of, " }%s\n", IDL_LIST (sub).next ? "," : ""); */
+
+/*             g_free (tc); */
+/*             arg_count++; */
+/*     } */
+
+/*     if (arg_count) */
+/*             fprintf (of, "};\n"); */
+/* } */
+
+/* static void */
+/* cc_output_contexts (FILE *of, const char *method, IDL_tree tree) */
+/* { */
+/*     /\* Build a list of contest names *\/ */
+/*     if (IDL_OP_DCL (tree).context_expr) { */
+/*             IDL_tree curitem; */
+
+/*             fprintf (of, "/\* Exceptions *\/\n"); */
+/*             fprintf (of, "static CORBA_string %s__contextinfo [] = {\n", */
+/*                      method); */
+
+/*             for (curitem = IDL_OP_DCL (tree).context_expr; curitem; */
+/*                  curitem = IDL_LIST (curitem).next) { */
+/*                     fprintf (of, "\"%s\"%c",  */
+/*                              IDL_STRING (IDL_LIST (curitem).data).value, */
+/*                              IDL_LIST (curitem).next ? ',' : ' '); */
+/*             } */
+
+/*             fprintf (of, "};\n"); */
+/*     } */
+/* } */
+
+/* static void */
+/* cc_output_exceptinfo (FILE *of, const char *method, IDL_tree tree) */
+/* { */
+/*     /\* Build a list of exception typecodes *\/ */
+/*     if (IDL_OP_DCL (tree).raises_expr) { */
+/*             IDL_tree curitem; */
+
+/*             fprintf (of, "/\* Exceptions *\/\n"); */
+/*             fprintf (of, "static CORBA_TypeCode %s__exceptinfo [] = {\n", */
+/*                      method); */
+               
+/*             for (curitem = IDL_OP_DCL (tree).raises_expr; curitem; */
+/*                  curitem = IDL_LIST(curitem).next) { */
+/*                     char *type_id; */
+/*                     IDL_tree curnode = IDL_LIST(curitem).data; */
+                       
+/*                     type_id = forb_cbe_get_typecode_name (curnode); */
+/*                     fprintf (of, "\t%s,\n", type_id); */
+/*                     g_free (type_id); */
+/*             } */
+/*             fprintf (of, "\tNULL\n};\n"); */
+/*     } */
+/* } */
+
+/* static void */
+/* cc_output_method_bits (IDL_tree tree, const char *id, OIDL_C_Info *ci) */
+/* { */
+/*     FILE *of = ci->fh; */
+/*     char *fullname; */
+
+/*     fullname = g_strconcat (id, "_", IDL_IDENT ( */
+/*             IDL_OP_DCL (tree).ident).str, NULL); */
+
+/*     cc_output_iargs (of, fullname, tree); */
+
+/*     cc_output_contexts (of, fullname, tree); */
+
+/*     cc_output_exceptinfo (of, fullname, tree); */
+
+/*     g_free (fullname); */
+/* } */
+
+/* static void */
+/* cc_output_method (FILE *of, IDL_tree tree, const char *id) */
+/* { */
+/*     int arg_count; */
+/*     int except_count; */
+/*     int context_count; */
+/*     const char *method; */
+/*     char       *fullname; */
+
+/*     fullname = g_strconcat (id, "_", IDL_IDENT ( */
+/*             IDL_OP_DCL (tree).ident).str, NULL); */
+
+/*     arg_count = IDL_list_length (IDL_OP_DCL (tree).parameter_dcls); */
+/*     except_count = IDL_list_length (IDL_OP_DCL (tree).raises_expr); */
+/*     context_count = IDL_list_length (IDL_OP_DCL (tree).context_expr); */
+       
+/*     fprintf (of, "\t{\n"); */
+
+/*     /\* IArgs arguments *\/ */
+/*     if (arg_count) */
+/*             fprintf (of, "\t\t{ %d, %d, %s__arginfo, FALSE },\n", */
+/*                      arg_count, arg_count, fullname); */
+/*     else */
+/*             fprintf (of, "\t\t{ 0, 0, NULL, FALSE },\n"); */
+
+/*     /\* IContexts contexts *\/ */
+/*     if (context_count) */
+/*             fprintf (of, "\t\t{ %d, %d, %s__contextinfo, FALSE },\n", */
+/*                      context_count, context_count, fullname); */
+/*     else */
+/*             fprintf (of, "\t\t{ 0, 0, NULL, FALSE },\n"); */
+               
+/*     /\* ITypes exceptions *\/ */
+/*     if (IDL_OP_DCL (tree).raises_expr) */
+/*             fprintf (of, "\t\t{ %d, %d, %s__exceptinfo, FALSE },\n", */
+/*                      except_count, except_count, fullname); */
+/*     else */
+/*             fprintf (of, "\t\t{ 0, 0, NULL, FALSE },\n"); */
+
+/*     /\* TypeCode ret *\/ */
+/*     if (IDL_OP_DCL (tree).op_type_spec) { */
+/*             char *type_id; */
+
+/*             type_id = forb_cbe_get_typespec_str ( */
+/*                     IDL_OP_DCL (tree).op_type_spec); */
+/*             fprintf (of, "\t\tTC_%s, ", type_id); */
+/*             g_free (type_id); */
+/*     } else */
+/*             fprintf (of, "TC_void, "); */
+
+/*     /\* string name, long name_len *\/ */
+/*     method = IDL_IDENT (IDL_OP_DCL (tree).ident).str; */
+/*     fprintf (of, "(char *)\"%s\", %d,\n", method, strlen (method)); */
+
+/*     /\* IMethodFlags flags *\/ */
+/*     fprintf (of, "\t\t0"); */
+
+/*     if (IDL_OP_DCL(tree).f_oneway) */
+/*             fprintf (of, " | Forb_I_METHOD_1_WAY"); */
+
+/* /\* FIXME: re-scan for no_out *\/ */
+/* /\* if (no_out) */
+/*     fprintf (of, " | Forb_I_METHOD_NO_OUT");*\/ */
+
+/*     if (IDL_OP_DCL (tree).op_type_spec && */
+/*         forb_cbe_type_is_fixed_length ( */
+/*                 IDL_OP_DCL (tree).op_type_spec)) */
+/*             fprintf (of, "| Forb_I_COMMON_FIXED_SIZE"); */
+
+/*     if (IDL_OP_DCL(tree).context_expr) */
+/*             fprintf (of, "| Forb_I_METHOD_HAS_CONTEXT"); */
+
+/*     fprintf (of, "\n}\n"); */
+
+/*     g_free (fullname); */
+/* } */
+
+/* static void */
+/* cc_output_base_itypes(IDL_tree node, CCSmallInterfaceTraverseInfo *iti) */
+/* { */
+/*     if (iti->cur_node == node) */
+/*             return; */
+
+/*     fprintf (iti->of, "(char *)\"%s\",\n", */
+/*              IDL_IDENT(IDL_INTERFACE(node).ident).repo_id); */
+
+/*     iti->parents++; */
+/* } */
+
+/* static void */
+/* cc_output_itypes (GSList *list, OIDL_C_Info *ci) */
+/* { */
+/*     GSList *l; */
+/*     FILE   *of = ci->fh; */
+
+/*     for (l = list; l; l = l->next) { */
+/*             CCSmallInterfaceTraverseInfo iti; */
+/*             Interface *i = l->data; */
+/*             char      *id; */
+/*             GSList    *m; */
+
+/*             id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS ( */
+/*                     IDL_INTERFACE (i->tree).ident), "_", 0); */
+
+/*             for (m = i->methods; m; m = m->next) */
+/*                     cc_output_method_bits (m->data, id, ci); */
+
+/*             if (i->methods) { */
+/*                     fprintf (of, "\n#ifdef FORB_IDL_C_IMODULE_%s\n", */
+/*                              ci->c_base_name); */
+/*                     fprintf (of, "static\n"); */
+/*                     fprintf (of, "#endif\n"); */
+
+/*                     fprintf (of, "Forb_IMethod %s__imethods [] = {\n", id); */
+
+/*                     if (!(m = i->methods)) */
+/*                             fprintf (of, "{{0}}"); */
+
+/*                     else for (; m; m = m->next) { */
+/*                             cc_output_method (of, m->data, id); */
+/*                             if (m->next) */
+/*                                     fprintf(of, ", "); */
+/*                     } */
+
+/*                     fprintf (of, "};\n\n"); */
+/*             } */
+
+/*             fprintf (of, "static CORBA_string %s__base_itypes[] = {\n", id); */
+
+/*             iti.of = of; */
+/*             iti.cur_node = i->tree; */
+/*             iti.cur_id = id; */
+/*             iti.parents = 0; */
+/*             IDL_tree_traverse_parents(i->tree, (GFunc)cc_output_base_itypes, &iti); */
+
+/*             fprintf (of, "(char *)\"IDL:omg.org/CORBA/Object:1.0\"\n};"); */
+
+/*             fprintf (of, "\n#ifdef FORB_IDL_C_IMODULE_%s\n", */
+/*                      ci->c_base_name); */
+/*             fprintf (of, "static\n"); */
+/*             fprintf (of, "#endif\n"); */
+/*             fprintf (of, "Forb_IInterface %s__iinterface = {\n", id); */
+/*             fprintf (of, "TC_%s,", id); */
+/*             fprintf (of, "{%d, %d, %s__imethods, FALSE},\n", */
+/*                      g_slist_length (i->methods), */
+/*                      g_slist_length (i->methods), id); */
+
+/*             fprintf (of, "{%d, %d, %s__base_itypes, FALSE}\n",  */
+/*                      iti.parents + 1, iti.parents + 1, id); */
+
+/*             fprintf (of, "};\n\n"); */
+
+/*             g_free (id); */
+/*     } */
+
+/*     for (l = list; l; l = l->next) { */
+/*             g_slist_free (((Interface *)l->data)->methods); */
+/*             g_free (l->data); */
+/*     } */
+
+/*     g_slist_free (list); */
+/* } */
+
+/* static GSList * */
+/* cc_build_interfaces (GSList *list, IDL_tree tree) */
+/* { */
+/*     if (!tree) */
+/*             return list; */
+
+/*     switch (IDL_NODE_TYPE (tree)) { */
+/*     case IDLN_MODULE: */
+/*             list = cc_build_interfaces ( */
+/*                     list, IDL_MODULE (tree).definition_list); */
+/*             break; */
+/*     case IDLN_LIST: { */
+/*             IDL_tree sub; */
+/*             for (sub = tree; sub; sub = IDL_LIST (sub).next) */
+/*                     list = cc_build_interfaces ( */
+/*                             list, IDL_LIST (sub).data); */
+/*             break; */
+/*     } */
+/*     case IDLN_ATTR_DCL: { */
+/*             IDL_tree curitem; */
+      
+/*             for (curitem = IDL_ATTR_DCL (tree).simple_declarations; */
+/*                  curitem; curitem = IDL_LIST (curitem).next) { */
+/*                     OIDL_Attr_Info *ai = IDL_LIST (curitem).data->data; */
+       
+/*                     list = cc_build_interfaces (list, ai->op1); */
+/*                     if (ai->op2) */
+/*                             list = cc_build_interfaces (list, ai->op2); */
+/*             } */
+/*             break; */
+/*     } */
+/*     case IDLN_INTERFACE: { */
+/*             Interface *i = g_new0 (Interface, 1); */
+
+/*             i->tree = tree; */
+
+/*             list = g_slist_append (list, i); */
+
+/*             list = cc_build_interfaces (list, IDL_INTERFACE(tree).body); */
+
+/*             break; */
+/*     } */
+/*     case IDLN_OP_DCL: { */
+/*             Interface *i; */
+
+/*             g_return_val_if_fail (list != NULL, NULL); */
+
+/*             i = ( g_slist_last(list) )->data; */
+/*             i->methods = g_slist_append (i->methods, tree); */
+/*             break; */
+/*     } */
+/*     case IDLN_EXCEPT_DCL: */
+/*             break; */
+/*     default: */
+/*             break; */
+/*     } */
+
+/*     return list; */
+/* } */
+
+/* static void */
+/* cc_output_skel (IDL_tree     tree, */
+/*             OIDL_C_Info *ci, */
+/*             int         *idx) */
+/* { */
+/*     IDL_tree  intf; */
+/*     gboolean  has_retval; */
+/*     char     *opname; */
+/*     char     *ifname; */
+
+/*     g_return_if_fail (idx != NULL); */
+
+/*     intf = IDL_get_parent_node (tree, IDLN_INTERFACE, NULL); */
+
+/*     has_retval = IDL_OP_DCL (tree).op_type_spec != NULL; */
+
+/*     opname = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_OP_DCL (tree).ident), "_", 0); */
+/*     ifname = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident), "_", 0); */
+
+/*     fprintf (ci->fh, "void _FORB_skel_small_%s(" */
+/*                             "POA_%s             *_o_servant, " */
+/*                             "gpointer            _o_retval," */
+/*                             "gpointer           *_o_args," */
+/*                             "CORBA_Context       _o_ctx," */
+/*                             "CORBA_Environment  *_o_ev,\n", opname, ifname); */
+
+/*     forb_cbe_op_write_proto (ci->fh, tree, "_impl_", TRUE); */
+
+/*     fprintf (ci->fh, ") {\n"); */
+
+/*     if (has_retval) { */
+/*             fprintf (ci->fh, "*("); */
+/*             forb_cbe_write_param_typespec (ci->fh, tree); */
+/*             fprintf (ci->fh, " *)_o_retval = "); */
+/*     } */
+
+/*     fprintf (ci->fh, "_impl_%s (_o_servant, ", IDL_IDENT (IDL_OP_DCL (tree).ident).str); */
+  
+/*     forb_cbe_unflatten_args (tree, ci->fh, "_o_args"); */
+
+/*     if (IDL_OP_DCL (tree).context_expr) */
+/*             fprintf (ci->fh, "_o_ctx, "); */
+
+/*     fprintf (ci->fh, "_o_ev);\n"); */
+
+/*     fprintf (ci->fh, "}\n"); */
+
+/*     g_free (opname); */
+/*     g_free (ifname); */
+
+/*     (*idx)++; */
+/* } */
+
+/* static void */
+/* cc_output_skels (IDL_tree       tree, */
+/*              OIDL_Run_Info *rinfo, */
+/*              OIDL_C_Info   *ci, */
+/*              int           *idx) */
+/* { */
+/*     if (!tree || (tree->declspec & IDLF_DECLSPEC_PIDL)) */
+/*             return; */
+
+/*     switch (IDL_NODE_TYPE (tree)) { */
+/*     case IDLN_MODULE: */
+/*             cc_output_skels (IDL_MODULE (tree).definition_list, rinfo, ci, idx); */
+/*             break; */
+/*     case IDLN_LIST: { */
+/*             IDL_tree node; */
+
+/*             for (node = tree; node; node = IDL_LIST (node).next) */
+/*                     cc_output_skels (IDL_LIST (node).data, rinfo, ci, idx); */
+/*             break; */
+/*             } */
+/*     case IDLN_ATTR_DCL: { */
+/*             OIDL_Attr_Info *ai = tree->data; */
+/*             IDL_tree        node; */
+      
+/*             for (node = IDL_ATTR_DCL (tree).simple_declarations; node; node = IDL_LIST (node).next) { */
+/*                     ai = IDL_LIST (node).data->data; */
+       
+/*                     cc_output_skels (ai->op1, rinfo, ci, idx); */
+/*                     if (ai->op2) */
+/*                             cc_output_skels (ai->op2, rinfo, ci, idx); */
+/*             } */
+/*             break; */
+/*             } */
+/*     case IDLN_INTERFACE: { */
+/*             int real_idx = 0; */
+
+/*             cc_output_skels (IDL_INTERFACE (tree).body, rinfo, ci, &real_idx); */
+/*             } */
+/*             break; */
+/*     case IDLN_OP_DCL: */
+/*             cc_output_skel (tree, ci, idx); */
+/*             break; */
+/*     default: */
+/*             break; */
+/*     } */
+/* } */
+
+void
+forb_idl_output_c_common (IDL_tree       tree,
+                          OIDL_Run_Info *rinfo,
+                          OIDL_C_Info   *ci)
+{
+       fprintf (ci->fh, OIDL_C_WARNING);
+/*     fprintf (ci->fh, "#include <string.h>\n"); */
+/*     fprintf (ci->fh, "#define FORB2_STUBS_API\n"); */
+/*     fprintf (ci->fh, "#define FORB_IDL_C_COMMON\n"); */
+/*     fprintf (ci->fh, "#define %s_COMMON\n", ci->c_base_name); */
+       fprintf (ci->fh, "#include \"%s.h\"\n", ci->base_name);
+       fprintf (ci->fh, "#include <forb/cdr.h>\n");
+       fprintf (ci->fh, "#include <forb/object.h>\n\n");
+/*     fprintf (ci->fh, "static const CORBA_unsigned_long Forb_zero_int = 0;\n"); */
+
+       /* FIXME: this is slightly nasty, but we need these in common,
+          and this fixes an internal build issue */
+/*     if (rinfo->enabled_passes & OUTPUT_SKELS || */
+/*         rinfo->enabled_passes & OUTPUT_STUBS) { */
+/*             fprintf (ci->fh, "\n#ifndef FORB_IDL_C_IMODULE_%s\n",ci->c_base_name); */
+/*             cc_output_skels (tree, rinfo, ci, NULL); */
+/*             fprintf (ci->fh, "\n#endif\n"); */
+/*     } */
+
+       cc_output_serialization (tree, ci);
+/*     cc_output_typecodes (tree, ci); */
+       
+/*     cc_output_class_ids (tree, rinfo, ci); */
+
+/*     if (rinfo->idata) { */
+/*             GSList *list = NULL; */
+
+/*             fprintf (ci->fh, "\n/\* Interface type data *\/\n\n"); */
+
+/*             list = cc_build_interfaces (list, tree); */
+/*             cc_output_itypes (list, ci); */
+/*     } */
+}
diff --git a/src/forb/forb-idl/forb-idl-c-deps.c b/src/forb/forb-idl/forb-idl-c-deps.c
new file mode 100644 (file)
index 0000000..0717cb3
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2001 Maciej Stachowiak, Ximian Inc.
+ */
+
+#include "config.h"
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+#include <ctype.h>
+
+static void
+output_deps (IDL_tree tree, 
+            OIDL_Run_Info *rinfo, 
+            OIDL_C_Info *ci)
+{
+       if (!tree)
+               return;
+
+       switch (IDL_NODE_TYPE (tree)) {
+       case IDLN_SRCFILE: {
+               char *idlfn = IDL_SRCFILE (tree).filename;
+               fprintf (ci->fh, " \\\n\t%s", idlfn);
+               break;
+       }
+
+       case IDLN_MODULE:
+               output_deps (IDL_MODULE (tree).definition_list, rinfo, ci);
+               break;
+
+       case IDLN_LIST: {
+               IDL_tree sub;
+
+               for (sub = tree; sub; sub = IDL_LIST (sub).next)
+                       output_deps (IDL_LIST (sub).data, rinfo, ci);
+               break;
+       }
+
+       case IDLN_INTERFACE:
+               output_deps (IDL_INTERFACE (tree).body, rinfo, ci);
+               break;
+
+       default:
+               break;
+       }
+}
+
+void
+forb_idl_output_c_deps (IDL_tree       tree,
+                        OIDL_Run_Info *rinfo, 
+                        OIDL_C_Info   *ci)
+{
+       int i;
+
+       g_return_if_fail (ci->fh != NULL);
+
+       for (i = 0; i < OUTPUT_NUM_PASSES - 1; i++) {
+               char *name = forb_idl_c_filename_for_pass (
+                       rinfo->input_filename, 1 << i);
+               fprintf (ci->fh, "%s ", name);
+               g_free (name);
+       }
+
+       fprintf (ci->fh, ": ");
+  
+       output_deps (tree, rinfo, ci);
+
+       fprintf (ci->fh, "\n");
+}
diff --git a/src/forb/forb-idl/forb-idl-c-headers.c b/src/forb/forb-idl/forb-idl-c-headers.c
new file mode 100644 (file)
index 0000000..6bb62b5
--- /dev/null
@@ -0,0 +1,1346 @@
+#include "config.h"
+#include "forb-idl-c-backend.h"
+#include "forb_config.h"
+
+#include <string.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+/* ch = C header */
+static void ch_output_types(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+/* static void ch_output_poa(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci); */
+/* static void ch_output_itypes (IDL_tree tree, OIDL_C_Info *ci); */
+static void ch_output_stub_protos(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+/* static void ch_output_skel_protos(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci); */
+static GSList *ch_build_interfaces (GSList *list, IDL_tree tree);
+static void ch_output_method (FILE *of, IDL_tree tree, const char *id);
+/* static void ch_output_imethods_index (GSList *list, OIDL_C_Info *ci); */
+
+typedef struct {
+    IDL_tree tree;
+    GSList  *methods; /* IDLN_OP_DCLs */
+} Interface;
+
+/* this is hardcopy from cc_build_interfaces() defined in forb-idl-c-common.c */
+static GSList *
+ch_build_interfaces (GSList *list, IDL_tree tree)
+{
+       if (!tree)
+               return list;
+
+       switch (IDL_NODE_TYPE (tree)) {
+       case IDLN_MODULE:
+               list = ch_build_interfaces (
+                       list, IDL_MODULE (tree).definition_list);
+               break;
+       case IDLN_LIST: {
+               IDL_tree sub;
+               for (sub = tree; sub; sub = IDL_LIST (sub).next)
+                       list = ch_build_interfaces (
+                               list, IDL_LIST (sub).data);
+               break;
+       }
+       case IDLN_ATTR_DCL: {
+               IDL_tree curitem;
+      
+               for (curitem = IDL_ATTR_DCL (tree).simple_declarations;
+                    curitem; curitem = IDL_LIST (curitem).next) {
+                       OIDL_Attr_Info *ai = IDL_LIST (curitem).data->data;
+       
+                       list = ch_build_interfaces (list, ai->op1);
+                       if (ai->op2)
+                               list = ch_build_interfaces (list, ai->op2);
+               }
+               break;
+       }
+       case IDLN_INTERFACE: {
+               Interface *i = g_new0 (Interface, 1);
+
+               i->tree = tree;
+
+               list = g_slist_append (list, i);
+
+               list = ch_build_interfaces (list, IDL_INTERFACE(tree).body);
+
+               break;
+       }
+       case IDLN_OP_DCL: {
+               Interface *i;
+
+               g_return_val_if_fail (list != NULL, NULL);
+
+               i = ( g_slist_last(list) )->data;
+               i->methods = g_slist_append (i->methods, tree);
+               break;
+       }
+       case IDLN_EXCEPT_DCL:
+               break;
+       default:
+               break;
+       }
+
+       return list;
+}
+                                                                                                   
+static void
+ch_output_method (FILE *of, IDL_tree tree, const char *id)
+{
+       char *fullname = NULL;
+
+       fullname = g_strconcat (id, "_", IDL_IDENT (
+               IDL_OP_DCL (tree).ident).str, NULL);
+
+       fprintf (of, "\t%s__method_index", fullname);
+
+       g_free (fullname);
+}
+
+static void
+ch_output_method_indices (GSList *list, OIDL_C_Info *ci)
+{
+       GSList *l;
+       FILE *of = ci->fh;
+
+       for (l = list; l; l = l->next) {
+               Interface *i = l->data;
+               char      *id;
+               GSList    *m;
+
+               id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (
+                       IDL_INTERFACE (i->tree).ident), "_", 0);
+
+               if (i->methods) {
+
+                       fprintf (of, "#ifndef __%s__method_indices\n", id);
+                       fprintf (of, "#define __%s__method_indices\n", id);
+
+                       fprintf (of, "typedef enum {\n");
+
+                       for (m = i->methods; m; m = m->next) {
+                               ch_output_method (of, m->data, id);
+                               if (m->next)
+                                       fprintf(of, ",\n");
+                               else
+                                       fprintf(of, "\n");
+                       }
+
+                       fprintf (of, "} %s__method_indices;\n", id);
+                       fprintf (of, "#endif /* __%s__method_indices */\n\n", id);
+               }
+
+               g_free (id);
+       }
+
+       for (l = list; l; l = l->next) {
+               g_slist_free (((Interface *)l->data)->methods);
+               g_free (l->data);
+       }
+
+       g_slist_free (list);
+}
+
+
+#if 0
+static gboolean is_native(IDL_tree_func_data *tfd, gpointer user_data)
+{
+       IDL_tree tree = tfd->tree;
+       if (IDL_NODE_TYPE (tree) == IDLN_NATIVE) {
+               *(bool*)user_data = true;
+               return FALSE;   /* Stop recursing */
+       }
+       return TRUE;            /* continue */
+}
+
+static bool
+contains_native_type(IDL_tree tree)
+{
+       bool found = false;
+       IDL_tree_walk_in_order(tree, is_native, &found);
+       return found;
+}
+#endif
+
+void
+forb_idl_output_c_headers (IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+  fprintf (ci->fh, OIDL_C_WARNING);
+  fprintf(ci->fh, "#ifndef %s%s_H\n", rinfo->header_guard_prefix, ci->c_base_name);
+  fprintf(ci->fh, "#define %s%s_H 1\n", rinfo->header_guard_prefix, ci->c_base_name);
+
+  fprintf(ci->fh, "#define FORB_IDL_SERIAL %d\n", FORB_CONFIG_SERIAL);
+
+  fprintf(ci->fh, "#include <forb/cdr_codec.h>\n");
+  if (!rinfo->is_pidl) {
+    fprintf(ci->fh, "#include <forb/object_type.h>\n");
+  }
+  fprintf(ci->fh, "#include <forb/basic_types.h>\n");
+  if (rinfo->include) {
+         fprintf(ci->fh, "#include <%s>\n", rinfo->include);
+  }
+  fprintf(ci->fh, "\n");
+
+  fprintf(ci->fh, "#ifdef __cplusplus\n");
+  fprintf(ci->fh, "extern \"C\" {\n");
+  fprintf(ci->fh, "#endif /* __cplusplus */\n\n");
+
+  /* Do all the typedefs, etc. */
+  fprintf(ci->fh, "\n/** typedefs **/\n");
+  ch_output_types(tree, rinfo, ci);
+  
+  if ( ci->do_skel_defs ) {
+/*     /\* Do all the POA structures, etc. *\/ */
+/*     fprintf(ci->fh, "\n/\** POA structures **\/\n"); */
+/*     ch_output_poa(tree, rinfo, ci); */
+
+/*     fprintf(ci->fh, "\n/\** skel prototypes **\/\n"); */
+/*     fprintf(ci->fh, "/\* FIXME: Maybe we don't need this for FORB. *\/\n"); */
+/*     ch_output_skel_protos(tree, rinfo, ci); */
+  }
+  fprintf(ci->fh, "\n/** stub prototypes **/\n");
+  ch_output_stub_protos(tree, rinfo, ci);
+
+/*   if ( ci->ext_dcls && ci->ext_dcls->str ) */
+/*     fputs( ci->ext_dcls->str, ci->fh);      /\* this may be huge! *\/ */
+
+/*   if (rinfo->idata) { */
+/*     /\* FIXME: hackish ? *\/ */
+/*     fprintf(ci->fh, "#include <forb/orb-core/forb-interface.h>\n\n"); */
+
+/*     ch_output_itypes(tree, ci); */
+/*   } */
+
+  if (rinfo->idata) {
+       GSList *list = NULL;
+       fprintf (ci->fh, "\n/** Method indices */\n\n");
+                                                                                                           
+       list = ch_build_interfaces (list, tree);
+       ch_output_method_indices (list, ci);
+  }
+
+  fprintf(ci->fh, "#ifdef __cplusplus\n");
+  fprintf(ci->fh, "}\n");
+  fprintf(ci->fh, "#endif /* __cplusplus */\n\n");
+
+/*   fprintf(ci->fh, "#ifndef EXCLUDE_FORB_H\n"); */
+/*   fprintf(ci->fh, "#include <forb.h>\n\n"); */
+/*   fprintf(ci->fh, "#endif /\* EXCLUDE_FORB_H *\/\n"); */
+
+  fprintf(ci->fh, "#endif\n");
+
+  fprintf(ci->fh, "#undef FORB_IDL_SERIAL\n");
+}
+
+static void
+ch_output_var(IDL_tree val, IDL_tree name, OIDL_C_Info *ci)
+{
+  forb_cbe_write_typespec(ci->fh, val);
+
+  fprintf(ci->fh, " ");
+  switch(IDL_NODE_TYPE(name)) {
+  case IDLN_IDENT:
+    fprintf(ci->fh, "%s", IDL_IDENT(name).str);
+    break;
+  case IDLN_TYPE_ARRAY:
+    {
+      IDL_tree curitem;
+
+      fprintf(ci->fh, "%s", IDL_IDENT(IDL_TYPE_ARRAY(name).ident).str);
+      for(curitem = IDL_TYPE_ARRAY(name).size_list; curitem; curitem = IDL_LIST(curitem).next) {
+       fprintf(ci->fh, "[%" PRId64 "]", IDL_INTEGER(IDL_LIST(curitem).data).value);
+      }
+    }
+    break;
+  default:
+    g_error("Weird varname - %s", IDL_tree_type_names[IDL_NODE_TYPE(name)]);
+    break;
+  }
+  fprintf(ci->fh, ";\n");
+}
+
+static void ch_output_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_output_type_struct(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_output_type_enum(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_output_type_dcl(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+/* static void ch_output_native(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci); */
+static void ch_output_type_union(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_output_codefrag(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_output_const_dcl(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_prep(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+/* static void ch_type_alloc_and_tc(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci, gboolean do_alloc); */
+
+static void
+ch_output_types (IDL_tree       tree,
+                OIDL_Run_Info *rinfo,
+                OIDL_C_Info   *ci)
+{
+       if (!tree)
+               return;
+       
+       switch (IDL_NODE_TYPE (tree)) {
+       case IDLN_EXCEPT_DCL: {
+         IDL_tree_warning(tree, IDL_WARNING1, "Exceptions are not supperted\n");
+/*             char *id; */
+
+/*             id = IDL_ns_ident_to_qstring ( */
+/*                     IDL_IDENT_TO_NS (IDL_EXCEPT_DCL (tree).ident), "_", 0); */
+
+/*             fprintf (ci->fh, "#undef ex_%s\n", id); */
+/*             fprintf (ci->fh, "#define ex_%s \"%s\"\n", */
+/*                             id, IDL_IDENT (IDL_EXCEPT_DCL (tree).ident).repo_id); */
+
+/*             g_free (id); */
+
+/*             ch_output_type_struct (tree, rinfo, ci); */
+               }
+               break;
+       case IDLN_FORWARD_DCL:
+       case IDLN_INTERFACE:
+               ch_output_interface (tree, rinfo, ci);
+               break;
+       case IDLN_TYPE_STRUCT:
+               ch_output_type_struct (tree, rinfo, ci);
+               break;
+       case IDLN_TYPE_ENUM:
+               ch_output_type_enum (tree, rinfo, ci);
+               break;
+       case IDLN_TYPE_DCL:
+               ch_output_type_dcl (tree, rinfo, ci);
+               break;
+       case IDLN_TYPE_UNION:
+               ch_output_type_union (tree, rinfo, ci);
+               break;
+       case IDLN_CODEFRAG:
+               ch_output_codefrag (tree, rinfo, ci);
+               break;
+       case IDLN_SRCFILE: {
+               char *idlfn = IDL_SRCFILE (tree).filename;
+               if (rinfo->onlytop) {
+
+                       if (!IDL_SRCFILE (tree).seenCnt &&
+                           !IDL_SRCFILE(tree).isTop    &&
+                           !IDL_SRCFILE(tree).wasInhibit) {
+                               gchar *hfn, *htail;
+
+                               hfn   = g_path_get_basename (idlfn);
+                               htail = strrchr (hfn,'.');
+
+                               g_assert (htail && strlen (htail) >= 2);
+
+                               htail [1] = 'h';
+                               htail [2] = 0;
+
+                               fprintf (ci->fh, "#include \"%s\"\n", hfn);
+
+                               g_free (hfn);
+                       }
+               } else {
+               fprintf (ci->fh, "/* from IDL source file \"%s\" "
+                                "(seen %d, isTop %d, wasInhibit %d) */ \n", 
+                                       idlfn,
+                                       IDL_SRCFILE (tree).seenCnt,
+                                       IDL_SRCFILE (tree).isTop,
+                                       IDL_SRCFILE (tree).wasInhibit);
+               }
+               }
+               break;
+       case IDLN_CONST_DCL:
+               ch_output_const_dcl (tree, rinfo, ci);
+               break;
+/*     case IDLN_NATIVE: */
+/*             ch_output_native (tree, rinfo, ci); */
+/*             break; */
+       default:
+               break;
+       }
+
+       switch (IDL_NODE_TYPE (tree)) {
+       case IDLN_MODULE:
+               ch_output_types (IDL_MODULE (tree).definition_list, rinfo, ci);
+               break;
+       case IDLN_LIST: {
+               IDL_tree sub;
+
+               for (sub = tree; sub; sub = IDL_LIST (sub).next) {
+                       ch_output_types (IDL_LIST (sub).data, rinfo, ci);
+               }
+               }
+               break;
+       case IDLN_INTERFACE:
+               ch_output_types (IDL_INTERFACE (tree).body, rinfo, ci);
+               break;
+       default:
+               break;
+       }
+}
+
+static void
+ch_output_impl_struct_members(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+  if(!tree) return;
+
+  switch(IDL_NODE_TYPE(tree)) {
+  case IDLN_LIST:
+    {
+      IDL_tree sub;
+
+      for(sub = tree; sub; sub = IDL_LIST(sub).next) {
+       ch_output_stub_protos(IDL_LIST(sub).data, rinfo, ci);
+      }
+    }
+    break;
+  case IDLN_INTERFACE:
+    {
+      IDL_tree sub;
+
+/*       if(IDL_INTERFACE(tree).inheritance_spec) { */
+/*     InheritedOutputInfo ioi; */
+/*     ioi.of = ci->fh; */
+/*     ioi.realif = tree; */
+/*     IDL_tree_traverse_parents(IDL_INTERFACE(tree).inheritance_spec, (GFunc)ch_output_inherited_protos, &ioi); */
+/*       } */
+
+      for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) {
+       IDL_tree cur;
+
+       cur = IDL_LIST(sub).data;
+
+       switch(IDL_NODE_TYPE(cur)) {
+       case IDLN_OP_DCL:
+         forb_idl_check_oneway_op (cur);
+         fprintf(ci->fh, "  ");
+         forb_cbe_op_write_proto(ci->fh, cur, "", TRUE);
+         fprintf(ci->fh, ";\n");
+         break;
+/*     case IDLN_ATTR_DCL: */
+/*       { */
+/*         OIDL_Attr_Info *ai; */
+/*         IDL_tree curitem; */
+
+/*         for(curitem = IDL_ATTR_DCL(cur).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) { */
+/*           ai = IDL_LIST(curitem).data->data; */
+             
+/*           forb_cbe_op_write_proto(ci->fh, ai->op1, "", FALSE); */
+/*           fprintf(ci->fh, ";\n"); */
+             
+/*           if(ai->op2) { */
+/*             forb_cbe_op_write_proto(ci->fh, ai->op2, "", FALSE); */
+/*             fprintf(ci->fh, ";\n"); */
+/*           } */
+/*         } */
+/*       } */
+/*       break; */
+       default:
+         break;
+       }
+      }
+    }
+    break;
+  default:
+    break;
+  }
+}
+static void
+ch_output_impl_struct(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+    char *fullname;
+    fullname = forb_cbe_get_typespec_str(tree);
+    fprintf(ci->fh, "struct forb_%s_impl {\n", fullname);
+    ch_output_impl_struct_members(tree, rinfo, ci);
+    fprintf(ci->fh, "};\n\n");
+    g_free(fullname);
+}
+
+static void
+ch_output_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+    char *fullname;
+    fullname = forb_cbe_get_typespec_str(tree);
+    fprintf(ci->fh, "#if !defined(FORB_DECL_%s)\n"
+                   "#define FORB_DECL_%s 1\n",
+                   fullname, fullname);
+
+    if ( tree->declspec & IDLF_DECLSPEC_PIDL ) {
+        /* PIDL interfaces are not normal CORBA Objects */
+      fprintf(ci->fh, "// PIDL: %s\n", fullname);
+/*             fprintf(ci->fh, "typedef struct %s_type *%s;\n", fullname, fullname); */
+/*     fprintf(ci->fh, "#ifndef TC_%s\n", fullname); */
+/*     fprintf(ci->fh, "#  define TC_%s TC_CORBA_Object\n", fullname); */
+/*     fprintf(ci->fh, "#endif\n"); */
+    } else {
+
+        fprintf(ci->fh, "  #if !defined(_%s_defined)\n"
+                       "  #define _%s_defined 1\n",
+                       fullname, fullname);
+/*         fprintf(ci->fh, "#define %s__freekids CORBA_Object__freekids\n", fullname); */
+       fprintf(ci->fh, "    typedef forb_object %s;\n"
+                       "  #endif\n", fullname);
+       fprintf(ci->fh, "  #define %s_serialize(codec, obj) forb_object_serialize((codec), (obj))\n", fullname);
+       fprintf(ci->fh, "  #define %s_deserialize(codec, obj) forb_object_deserialize((codec), (obj))\n", fullname);
+/*             fprintf(ci->fh, "extern CORBA_unsigned_long %s__classid;\n", fullname); */
+
+       ch_output_impl_struct(tree, rinfo, ci);
+
+/*     fprintf(ci->fh, "void forb_register_%s_interface(void);\n", fullname); */
+       fprintf(ci->fh, "  %s forb_%s_new(forb_orb orb,\n"
+                       "                 const struct forb_%s_impl *impl,\n"
+                       "                 void *instance_data);\n\n",
+               fullname, fullname, fullname);
+       
+       /* ch_type_alloc_and_tc(tree, rinfo, ci, FALSE); */
+    }
+
+    fprintf(ci->fh, "#endif\n\n");
+    g_free(fullname);
+}
+
+static void
+ch_output_type_enum (IDL_tree       tree,
+                    OIDL_Run_Info *rinfo,
+                    OIDL_C_Info   *ci)
+{
+       IDL_tree  l;
+       char     *enumid;
+
+       /* CORBA spec says to do
+        * typedef unsigned int enum_name;
+        * and then #defines for each enumerator.
+        * This works just as well and seems cleaner.
+        */
+
+       enumid = IDL_ns_ident_to_qstring (
+                       IDL_IDENT_TO_NS (IDL_TYPE_ENUM (tree).ident), "_", 0);
+       fprintf (ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n", enumid, enumid);
+       fprintf (ci->fh, "typedef enum {\n");
+
+       for (l = IDL_TYPE_ENUM (tree).enumerator_list; l; l = IDL_LIST (l).next) {
+               char *id;
+
+               id = IDL_ns_ident_to_qstring (
+                       IDL_IDENT_TO_NS (IDL_LIST (l).data), "_", 0);
+
+               fprintf (ci->fh, "  %s%s\n", id, IDL_LIST (l).next ? "," : "");
+
+               g_free (id);
+       }
+
+       fprintf (ci->fh, "} %s;\n", enumid);
+
+       /* ch_type_alloc_and_tc (tree, rinfo, ci, FALSE); */
+       fprintf (ci->fh, "#define %s_serialize(codec, val) CORBA_unsigned_long_serialize(codec, val)\n", enumid);
+       fprintf (ci->fh, "#define %s_deserialize(codec, val) CORBA_unsigned_long_deserialize(codec, val)\n", enumid);
+
+       fprintf (ci->fh, "#endif\n\n");
+
+       g_free (enumid);
+}
+
+static void
+ch_output_type_dcl(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+       IDL_tree  l;
+
+       ch_prep (IDL_TYPE_DCL (tree).type_spec, rinfo, ci);
+
+       for (l = IDL_TYPE_DCL (tree).dcls; l; l = IDL_LIST (l).next) {
+               char *ctmp = NULL;
+
+               IDL_tree ent = IDL_LIST (l).data;
+
+               switch (IDL_NODE_TYPE(ent)) {
+               case IDLN_IDENT:
+                       ctmp = IDL_ns_ident_to_qstring (
+                                       IDL_IDENT_TO_NS (ent), "_", 0);
+                       break;
+               case IDLN_TYPE_ARRAY:
+                       ctmp = IDL_ns_ident_to_qstring (
+                                       IDL_IDENT_TO_NS (IDL_TYPE_ARRAY (ent).ident), "_", 0);
+                       break;
+               default:
+                       g_assert_not_reached ();
+                       break;
+               }
+
+               fprintf (ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n", ctmp, ctmp);
+               fprintf (ci->fh, "typedef ");
+               forb_cbe_write_typespec (ci->fh, IDL_TYPE_DCL (tree).type_spec);
+
+               switch (IDL_NODE_TYPE (ent)) {
+               case IDLN_IDENT:
+                       fprintf (ci->fh, " %s;\n", ctmp);
+                       fprintf (ci->fh, "#define %s_serialize(x,y) ", ctmp);
+                       forb_cbe_write_typespec (ci->fh, IDL_TYPE_DCL (tree).type_spec);
+                       fprintf (ci->fh, "_serialize((x),(y))\n");
+
+                       fprintf (ci->fh, "#define %s_deserialize(x,y) ", ctmp);
+                       forb_cbe_write_typespec (ci->fh, IDL_TYPE_DCL (tree).type_spec);
+                       fprintf (ci->fh, "_deserialize((x),(y))\n");
+                       break;
+               case IDLN_TYPE_ARRAY: {
+                       IDL_tree sub;
+
+                       fprintf (ci->fh, " %s", ctmp);
+                       for (sub = IDL_TYPE_ARRAY (ent).size_list; sub; sub = IDL_LIST (sub).next)
+                               fprintf (ci->fh, "[%" PRId64 "]",
+                                        IDL_INTEGER (IDL_LIST (sub).data).value);
+
+                       fprintf (ci->fh, ";\n");
+                       fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s array);\n", ctmp, ctmp);
+                       fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s array);\n", ctmp, ctmp);
+/*                     fprintf (ci->fh, "typedef "); */
+/*                     forb_cbe_write_typespec (ci->fh, IDL_TYPE_DCL (tree).type_spec); */
+/*                     fprintf (ci->fh, " %s_slice", ctmp); */
+/*                     for (sub = IDL_LIST (IDL_TYPE_ARRAY (ent).size_list).next; */
+/*                          sub; sub = IDL_LIST (sub).next) */
+/*                             fprintf (ci->fh, "[%" PRId64 "d]", IDL_INTEGER (IDL_LIST (sub).data).value); */
+/*                     fprintf(ci->fh, ";\n"); */
+                       }
+                       break;
+               default:
+                       break;
+               }
+
+               /* ch_type_alloc_and_tc (ent, rinfo, ci, TRUE); */
+               fprintf (ci->fh, "#endif\n");
+               g_free (ctmp);
+       }
+}
+
+/* static void */
+/* ch_output_native(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci) */
+/* { */
+/*     char *ctmp; */
+/*     IDL_tree id = IDL_NATIVE(tree).ident; */
+/*     ctmp = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(id), "_", 0); */
+/*     fprintf(ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n", ctmp, ctmp); */
+/*     fprintf(ci->fh, "typedef struct %s_type *%s;\n", ctmp, ctmp); */
+/*     /\* Dont even think about emitting a typecode. *\/ */
+/*     fprintf(ci->fh, "#endif\n"); */
+/*     g_free(ctmp); */
+/* } */
+
+static void
+ch_output_type_struct(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+  char *id;
+  IDL_tree cur, curmem;
+
+  id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_TYPE_STRUCT(tree).ident), 
+    "_", 0);
+  fprintf(ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n", id, id);
+  /* put typedef out first for recursive seq */
+  fprintf(ci->fh, "typedef struct %s_type %s;\n", id, id);
+
+  /* Scan for any nested decls */
+  for(cur = IDL_TYPE_STRUCT(tree).member_list; cur; cur = IDL_LIST(cur).next) {
+    IDL_tree ts;
+    ts = IDL_MEMBER(IDL_LIST(cur).data).type_spec;
+    ch_prep(ts, rinfo, ci);
+  }
+
+  fprintf(ci->fh, "struct %s_type {\n", id);
+
+  for(cur = IDL_TYPE_STRUCT(tree).member_list; cur; cur = IDL_LIST(cur).next) {
+    for(curmem = IDL_MEMBER(IDL_LIST(cur).data).dcls; curmem; curmem = IDL_LIST(curmem).next) {
+      ch_output_var(IDL_MEMBER(IDL_LIST(cur).data).type_spec, IDL_LIST(curmem).data, ci);
+    }
+  }
+  if(!IDL_TYPE_STRUCT(tree).member_list)
+    fprintf(ci->fh, "int dummy;\n");
+  fprintf(ci->fh, "};\n");
+
+  fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s *ptr);\n", id, id);
+  fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s *ptr);\n", id, id);
+
+  /* ch_type_alloc_and_tc(tree, rinfo, ci, TRUE); */
+
+  fprintf(ci->fh, "#endif\n\n");
+
+  g_free(id);
+}
+
+
+static void
+ch_output_type_union(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+  char *id;
+  IDL_tree curitem;
+
+  if (IDL_NODE_TYPE (IDL_TYPE_UNION (tree).switch_type_spec) == IDLN_TYPE_ENUM)
+    ch_output_type_enum (IDL_TYPE_UNION (tree).switch_type_spec, rinfo, ci);
+
+  id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_TYPE_UNION(tree).ident), "_", 0);
+  fprintf(ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n", id, id);
+  fprintf(ci->fh, "typedef struct %s_type %s;\n", id, id);
+
+  /* Scan for any nested decls */
+  for(curitem = IDL_TYPE_UNION(tree).switch_body; curitem; curitem = IDL_LIST(curitem).next) {
+    IDL_tree member = IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec;
+    ch_prep(IDL_MEMBER(member).type_spec, rinfo, ci);
+  }
+
+  fprintf(ci->fh, "struct %s_type {\n", id);
+  forb_cbe_write_typespec(ci->fh, IDL_TYPE_UNION(tree).switch_type_spec);
+  fprintf(ci->fh, " _d;\nunion {\n");
+
+  for(curitem = IDL_TYPE_UNION(tree).switch_body; curitem; curitem = IDL_LIST(curitem).next) {
+    IDL_tree member;
+
+    member = IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec;
+    ch_output_var(IDL_MEMBER(member).type_spec,
+                 IDL_LIST(IDL_MEMBER(member).dcls).data,
+                 ci);
+  }
+
+  fprintf(ci->fh, "} _u;\n};\n");
+
+  /* ch_type_alloc_and_tc(tree, rinfo, ci, TRUE); */
+
+  fprintf(ci->fh, "#endif\n");
+
+  g_free(id);
+}
+
+static void
+ch_output_codefrag(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+  GSList *list;
+
+  for(list = IDL_CODEFRAG(tree).lines; list;
+      list = g_slist_next(list)) {
+    if(!strncmp(list->data,
+               "#pragma include_defs",
+               sizeof("#pragma include_defs")-1)) {
+       char *ctmp, *cte;
+       ctmp = ((char *)list->data) + sizeof("#pragma include_defs");
+       while(*ctmp && (isspace((int)*ctmp) || *ctmp == '"')) ctmp++;
+       cte = ctmp;
+       while(*cte && !isspace((int)*cte) && *cte != '"') cte++;
+       *cte = '\0';
+      fprintf(ci->fh, "#include <%s>\n", ctmp);
+    } else
+      fprintf(ci->fh, "%s\n", (char *)list->data);
+  }
+}
+
+static void
+ch_output_const_dcl(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+       char    *id;
+       IDL_tree ident;
+       IDL_tree typespec;
+
+       ident = IDL_CONST_DCL (tree).ident;
+       id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS (ident), "_", 0);
+
+       fprintf(ci->fh, "#ifndef %s\n", id);
+       fprintf(ci->fh, "#define %s ", id);
+
+       forb_cbe_write_const(ci->fh,
+                             IDL_CONST_DCL(tree).const_exp);
+
+       typespec = forb_cbe_get_typespec (IDL_CONST_DCL(tree).const_type);
+       if (IDL_NODE_TYPE (typespec) == IDLN_TYPE_INTEGER &&
+           !IDL_TYPE_INTEGER (typespec).f_signed)
+               fprintf(ci->fh, "U");
+
+       fprintf(ci->fh, "\n");
+       fprintf(ci->fh, "#endif /* !%s */\n\n", id);
+
+       g_free(id);
+}
+
+static void
+ch_prep_fixed(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+  char *ctmp;
+
+  ctmp = forb_cbe_get_typespec_str(tree);
+  fprintf(ci->fh,
+         "typedef struct { CORBA_unsigned_short _digits; CORBA_short _scale; CORBA_char _value[%d]; } %s;\n",
+         (int) (IDL_INTEGER(IDL_TYPE_FIXED(tree).positive_int_const).value + 2)/2,
+         ctmp);
+  g_free(ctmp);
+
+  /* ch_type_alloc_and_tc(tree, rinfo, ci, TRUE); */
+}
+
+static void
+ch_prep_sequence(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+  char *ctmp, *fullname, *fullname_def, *ctmp2;
+  IDL_tree tts;
+  gboolean separate_defs, fake_if;
+  IDL_tree fake_seq = NULL;
+
+  tts = forb_cbe_get_typespec(IDL_TYPE_SEQUENCE(tree).simple_type_spec);
+  ctmp = forb_cbe_get_typespec_str(IDL_TYPE_SEQUENCE(tree).simple_type_spec);
+  ctmp2 = forb_cbe_get_typespec_str(tts);
+  fake_if = (IDL_NODE_TYPE(tts) == IDLN_INTERFACE);
+  if(fake_if)
+    {
+      g_free(ctmp2);
+      ctmp2 = g_strdup("CORBA_Object");
+    }
+  separate_defs = false; //strcmp(ctmp, ctmp2);
+  fullname = forb_cbe_get_typespec_str(tree);
+  //printf("YYY %s\n", fullname);
+
+  if(separate_defs)
+    {
+      char *member_type;
+      //printf("XXXXXXXX Separate defs %s, %s\n", ctmp, ctmp2);
+      //forb_idl_print_node(tree, 2);
+      if(fake_if)
+       tts = IDL_type_object_new();
+      fake_seq = IDL_type_sequence_new(tts, NULL);
+      IDL_NODE_UP(fake_seq) = IDL_NODE_UP(tree);
+      ch_prep_sequence(fake_seq, rinfo, ci);
+      member_type = forb_cbe_type_is_builtin (tts) ?
+       ctmp2 + strlen ("CORBA_") : ctmp2;
+      fullname_def = g_strdup_printf("CORBA_sequence_%s", member_type);
+
+      if(!fake_if)
+       IDL_TYPE_SEQUENCE(fake_seq).simple_type_spec = NULL;
+    }
+  else
+    fullname_def = g_strdup(fullname);
+
+  if(IDL_NODE_TYPE(IDL_TYPE_SEQUENCE(tree).simple_type_spec)
+     == IDLN_TYPE_SEQUENCE)
+    ch_prep_sequence(IDL_TYPE_SEQUENCE(tree).simple_type_spec, rinfo, ci);
+
+  /* NOTE: FORB_DECL_%s protects redef of everything (struct,TC,externs)
+   * while _%s_defined protects only the struct */
+
+  fprintf(ci->fh, "#if !defined(FORB_DECL_%s)\n#define FORB_DECL_%s 1\n",
+         fullname, fullname);
+/*   if ( ci->do_impl_hack ) */
+/*       forb_cbe_id_define_hack(ci->fh, "FORB_IMPL", fullname, ci->c_base_name); */
+
+  if(separate_defs)
+    {
+      fprintf(ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n",
+             fullname, fullname);
+      if(!strcmp(ctmp, "CORBA_RepositoryId"))
+       fprintf(ci->fh, "/* CRACKHEADS */\n");
+      fprintf(ci->fh, "typedef %s\n  %s;\n", fullname_def, fullname);
+      fprintf(ci->fh, "#endif\n");
+      /* ch_type_alloc_and_tc(tree, rinfo, ci, FALSE); */
+/*       fprintf(ci->fh, "#define %s__alloc %s__alloc\n", */
+/*           fullname, fullname_def); */
+/*       fprintf(ci->fh, "#define %s__freekids %s__freekids\n", */
+/*           fullname, fullname_def); */
+      fprintf(ci->fh, "#define CORBA_sequence_%s_allocbuf(l) %s_allocbuf(l)\n",
+             ctmp, fullname_def);
+      fprintf(ci->fh, "#define %s_serialize(x,y) %s_serialize((x),(y))\n", fullname, fullname_def);
+
+      fprintf(ci->fh, "#define %s_deserialize(x,y) %s_deserialize((x),(y))\n", fullname, fullname_def);
+      IDL_tree_free(fake_seq);
+    }
+  else
+    {
+      char *member_type;
+
+      fprintf(ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n",
+             fullname, fullname);
+      fprintf(ci->fh, "typedef struct { CORBA_unsigned_long _maximum, _length; ");
+      forb_cbe_write_typespec(ci->fh, IDL_TYPE_SEQUENCE(tree).simple_type_spec);
+      fprintf(ci->fh, "* _buffer; CORBA_boolean _release; }\n  ");
+      forb_cbe_write_typespec(ci->fh, tree);
+      fprintf(ci->fh, ";\n#endif\n");
+
+      fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s *ptr);\n", fullname, fullname);
+      fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s *ptr);\n", fullname, fullname);
+      /* ch_type_alloc_and_tc(tree, rinfo, ci, TRUE); */
+
+/*       tc = forb_cbe_get_typecode_name (forb_cbe_get_typespec (tree)); */
+      member_type = forb_cbe_type_is_builtin (IDL_TYPE_SEQUENCE (tree).simple_type_spec) ?
+       ctmp + strlen ("CORBA_") : ctmp;
+
+      fprintf (ci->fh, "#define CORBA_sequence_%s_allocbuf(l) "
+                      "((%s*)forb_malloc(sizeof(%s)*(l)))\n",
+                      member_type, ctmp, ctmp);
+
+/*       g_free (tc); */
+    }
+
+  fprintf(ci->fh, "#endif\n\n");
+
+  g_free(ctmp2);
+  g_free(ctmp);
+  g_free(fullname);
+  g_free(fullname_def);
+}
+
+static
+void ch_prep (IDL_tree       tree,
+             OIDL_Run_Info *rinfo,
+             OIDL_C_Info   *ci)
+{
+       switch (IDL_NODE_TYPE (tree)) {
+       case IDLN_TYPE_SEQUENCE:
+               ch_prep_sequence (tree, rinfo, ci);
+               break;
+       case IDLN_TYPE_FIXED:
+               ch_prep_fixed (tree, rinfo, ci);
+               break;
+       case IDLN_TYPE_STRUCT:
+               ch_output_type_struct (tree, rinfo, ci);
+               break;
+       case IDLN_TYPE_ENUM:
+               ch_output_type_enum (tree, rinfo, ci);
+               break;
+       default:
+               break;
+       }
+}
+
+/* static void */
+/* ch_type_alloc_and_tc(IDL_tree tree, OIDL_Run_Info *rinfo, */
+/*                  OIDL_C_Info *ci, gboolean do_alloc) */
+/* { */
+/*   char *ctmp; */
+/*   IDL_tree tts; */
+
+/*   ctmp = forb_cbe_get_typespec_str(tree); */
+
+/*   if ( ci->do_impl_hack ) { */
+/*       fprintf(ci->fh, "#if !defined(TC_IMPL_TC_%s_0)\n", ctmp); */
+/*       forb_cbe_id_define_hack(ci->fh, "TC_IMPL_TC", ctmp, ci->c_base_name); */
+/*   } */
+
+/*   fprintf (ci->fh, "#ifdef FORB_IDL_C_IMODULE_%s\n", ci->c_base_name); */
+/*   fprintf (ci->fh, "static\n"); */
+/*   fprintf (ci->fh, "#else\n"); */
+/*   fprintf (ci->fh, "extern\n"); */
+/*   fprintf (ci->fh, "#endif\n"); */
+/*   fprintf (ci->fh, "FORB2_MAYBE_CONST struct CORBA_TypeCode_struct TC_%s_struct;\n", ctmp); */
+
+/*   fprintf (ci->fh, "#define TC_%s ((CORBA_TypeCode)&TC_%s_struct)\n", ctmp, ctmp); */
+/*   if (ci->do_impl_hack) */
+/*       fprintf (ci->fh, "#endif\n"); */
+
+/*   if(do_alloc) { */
+/*       char *tc; */
+
+/*       tts = forb_cbe_get_typespec(tree); */
+
+/*       tc = forb_cbe_get_typecode_name (tts); */
+
+/*       fprintf (ci->fh, "#define %s__alloc() ((%s%s *)Forb_small_alloc (%s))\n", */
+/*                ctmp, ctmp, (IDL_NODE_TYPE(tree) == IDLN_TYPE_ARRAY)?"_slice":"", tc); */
+
+/*       fprintf (ci->fh, "#define %s__freekids(m,d) Forb_small_freekids (%s,(m),(d))\n", ctmp, tc); */
+
+/*       if ( IDL_NODE_TYPE(tts) == IDLN_TYPE_SEQUENCE ) */
+/*       { */
+/*     char *member_type = forb_cbe_get_typespec_str(IDL_TYPE_SEQUENCE(tts).simple_type_spec); */
+/*     char *member_name = forb_cbe_type_is_builtin (IDL_TYPE_SEQUENCE (tts).simple_type_spec) ? */
+/*       member_type + strlen ("CORBA_") : member_type; */
+       
+/*     fprintf (ci->fh, "#define %s_allocbuf(l) " */
+/*              "((%s*)Forb_small_allocbuf (%s, (l)))\n", */
+/*              ctmp, member_name, tc); */
+       
+/*     g_free (member_type); */
+/*       } */
+       
+/*       g_free (tc); */
+/*   } */
+
+/*   g_free(ctmp); */
+/* } */
+
+/************************/
+/* static void */
+/* cbe_header_interface_print_vepv(IDL_tree node, FILE *of) */
+/* { */
+/*   char *id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(node).ident), */
+/*                                  "_", 0); */
+/*   fprintf(of, "  POA_%s__epv *%s_epv;\n", id, id); */
+/*   g_free(id); */
+
+/* } */
+
+/* static void */
+/* ch_output_poa(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci) */
+/* { */
+/*   if(!tree) return; */
+
+/*   if ( tree->declspec & IDLF_DECLSPEC_PIDL ) */
+/*     return; */
+
+/*   switch(IDL_NODE_TYPE(tree)) { */
+/*   case IDLN_MODULE: */
+/*     ch_output_poa(IDL_MODULE(tree).definition_list, rinfo, ci); */
+/*     break; */
+/*   case IDLN_LIST: */
+/*     { */
+/*       IDL_tree sub; */
+
+/*       for(sub = tree; sub; sub = IDL_LIST(sub).next) { */
+/*     ch_output_poa(IDL_LIST(sub).data, rinfo, ci); */
+/*       } */
+/*     } */
+/*     break; */
+/*   case IDLN_INTERFACE: */
+/*     { */
+/*       IDL_tree sub; */
+/*       char *id; */
+
+
+/*       id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0); */
+
+/*       fprintf(ci->fh, "#ifndef _defined_POA_%s\n#define _defined_POA_%s 1\n",  */
+/*         id, id); */
+
+/*       /\* First, do epv for this interface, then vepv, then servant *\/ */
+/*       fprintf(ci->fh, "typedef struct {\n"); */
+/*       fprintf(ci->fh, "  void *_private;\n"); */
+/*       for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) { */
+/*     IDL_tree cur; */
+
+/*     cur = IDL_LIST(sub).data; */
+
+/*     switch(IDL_NODE_TYPE(cur)) { */
+/*     case IDLN_OP_DCL: */
+/*       forb_cbe_op_write_proto(ci->fh, cur, "", TRUE); */
+/*       fprintf(ci->fh, ";\n"); */
+/*       break; */
+/*     case IDLN_ATTR_DCL: */
+/*       { */
+/*         OIDL_Attr_Info *ai; */
+/*         IDL_tree curitem; */
+
+/*         for(curitem = IDL_ATTR_DCL(cur).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) { */
+/*           ai = IDL_LIST(curitem).data->data; */
+             
+/*           forb_cbe_op_write_proto(ci->fh, ai->op1, "", TRUE); */
+/*           fprintf(ci->fh, ";\n"); */
+             
+/*           if(ai->op2) { */
+/*             forb_cbe_op_write_proto(ci->fh, ai->op2, "", TRUE); */
+/*             fprintf(ci->fh, ";\n"); */
+/*           } */
+/*         } */
+/*       } */
+/*       break; */
+/*     default: */
+/*       break; */
+/*     } */
+/*       } */
+
+/*       fprintf(ci->fh, "} POA_%s__epv;\n", id); */
+
+/*       fprintf(ci->fh, "typedef struct {\n"); */
+/*       fprintf(ci->fh, "  PortableServer_ServantBase__epv *_base_epv;\n"); */
+/*       IDL_tree_traverse_parents(tree, (GFunc)cbe_header_interface_print_vepv, ci->fh); */
+/*       fprintf(ci->fh, "} POA_%s__vepv;\n", id); */
+
+/*       fprintf(ci->fh, "typedef struct {\n"); */
+/*       fprintf(ci->fh, "  void *_private;\n"); */
+/*       fprintf(ci->fh, "  POA_%s__vepv *vepv;\n", id); */
+/*       fprintf(ci->fh, "} POA_%s;\n", id); */
+
+/*       fprintf(ci->fh, */
+/*           "extern void POA_%s__init(PortableServer_Servant servant, CORBA_Environment *ev);\n", id); */
+/*       fprintf(ci->fh, */
+/*           "extern void POA_%s__fini(PortableServer_Servant servant, CORBA_Environment *ev);\n", id); */
+
+/*       fprintf(ci->fh, "#endif /\* _defined_POA_%s *\/\n", id); */
+
+/*       g_free(id); */
+/*     } */
+/*     break; */
+/*   default: */
+/*     break; */
+/*   } */
+/* } */
+
+/************************/
+typedef struct {
+  FILE *of;
+  IDL_tree realif;
+} InheritedOutputInfo;
+static void ch_output_inherited_protos(IDL_tree curif, InheritedOutputInfo *ioi);
+
+static void
+ch_output_stub_protos(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+  if(!tree) return;
+
+
+  switch(IDL_NODE_TYPE(tree)) {
+  case IDLN_MODULE:
+    ch_output_stub_protos(IDL_MODULE(tree).definition_list, rinfo, ci);
+    break;
+  case IDLN_LIST:
+    {
+      IDL_tree sub;
+
+      for(sub = tree; sub; sub = IDL_LIST(sub).next) {
+       ch_output_stub_protos(IDL_LIST(sub).data, rinfo, ci);
+      }
+    }
+    break;
+  case IDLN_INTERFACE:
+    {
+      IDL_tree sub;
+
+      if(IDL_INTERFACE(tree).inheritance_spec) {
+       InheritedOutputInfo ioi;
+       ioi.of = ci->fh;
+       ioi.realif = tree;
+       IDL_tree_traverse_parents(IDL_INTERFACE(tree).inheritance_spec, (GFunc)ch_output_inherited_protos, &ioi);
+      }
+
+      for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) {
+       IDL_tree cur;
+
+       cur = IDL_LIST(sub).data;
+
+       switch(IDL_NODE_TYPE(cur)) {
+       case IDLN_OP_DCL:
+         forb_idl_check_oneway_op (cur);
+         forb_cbe_op_write_proto(ci->fh, cur, "", FALSE);
+         fprintf(ci->fh, ";\n");
+         break;
+       case IDLN_ATTR_DCL:
+         {
+           OIDL_Attr_Info *ai;
+           IDL_tree curitem;
+
+           for(curitem = IDL_ATTR_DCL(cur).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) {
+             ai = IDL_LIST(curitem).data->data;
+             
+             forb_cbe_op_write_proto(ci->fh, ai->op1, "", FALSE);
+             fprintf(ci->fh, ";\n");
+             
+             if(ai->op2) {
+               forb_cbe_op_write_proto(ci->fh, ai->op2, "", FALSE);
+               fprintf(ci->fh, ";\n");
+             }
+           }
+         }
+         break;
+       default:
+         break;
+       }
+      }
+    }
+    break;
+  default:
+    break;
+  }
+}
+
+static void
+ch_output_inherited_protos(IDL_tree curif, InheritedOutputInfo *ioi)
+{
+  char *id, *realid;
+  IDL_tree curitem;
+
+  if(curif == ioi->realif)
+    return;
+
+  realid = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ioi->realif).ident), "_", 0);
+  id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(curif).ident), "_", 0);
+
+  for(curitem = IDL_INTERFACE(curif).body; curitem; curitem = IDL_LIST(curitem).next) {
+    IDL_tree curop = IDL_LIST(curitem).data;
+
+    switch(IDL_NODE_TYPE(curop)) {
+    case IDLN_OP_DCL:
+      fprintf(ioi->of, "#define %s_%s %s_%s\n",
+             realid, IDL_IDENT(IDL_OP_DCL(curop).ident).str,
+             id, IDL_IDENT(IDL_OP_DCL(curop).ident).str);
+      break;
+    case IDLN_ATTR_DCL:
+      {
+       IDL_tree curitem;
+
+       /* We don't use OIDL_Attr_Info here because inherited ops may go back into trees that are output-inhibited
+          and therefore don't have the OIDL_Attr_Info generated on them */
+
+       for(curitem = IDL_ATTR_DCL(curop).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) {
+         IDL_tree ident;
+
+         ident = IDL_LIST(curitem).data;
+         
+         fprintf(ioi->of, "#define %s__get_%s %s__get_%s\n",
+                 realid, IDL_IDENT(ident).str,
+                 id, IDL_IDENT(ident).str);
+
+         if(!IDL_ATTR_DCL(curop).f_readonly)
+           fprintf(ioi->of, "#define %s__set_%s %s__set_%s\n",
+                   realid, IDL_IDENT(ident).str,
+                   id, IDL_IDENT(ident).str);
+       }
+      }
+      break;
+       default:
+         break;
+    }
+  }
+
+  g_free(id);
+  g_free(realid);
+}
+
+/* static void */
+/* doskel(IDL_tree cur, OIDL_Run_Info *rinfo, char *ifid, OIDL_C_Info *ci) */
+/* { */
+/*   char *id; */
+
+/*   id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(cur).ident), "_", 0); */
+
+/*   fprintf(ci->fh, "void _forb_skel_%s(" */
+/*       "FORB_CDR_Codec *codec, %s *obj", */
+/*       id, ifid); */
+/* /\*   forb_cbe_op_write_proto(ci->fh, cur, "_impl_", TRUE); *\/ */
+/*   fprintf(ci->fh, ");\n"); */
+
+/*   g_free(id); */
+/* } */
+
+/* static void */
+/* ch_output_skel_protos(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci) */
+/* { */
+/*   if(!tree) return; */
+
+/*   if ( tree->declspec & IDLF_DECLSPEC_PIDL ) */
+/*     return; */
+
+/*   switch(IDL_NODE_TYPE(tree)) { */
+/*   case IDLN_MODULE: */
+/*     ch_output_skel_protos(IDL_MODULE(tree).definition_list, rinfo, ci); */
+/*     break; */
+/*   case IDLN_LIST: */
+/*     { */
+/*       IDL_tree sub; */
+
+/*       for(sub = tree; sub; sub = IDL_LIST(sub).next) { */
+/*     ch_output_skel_protos(IDL_LIST(sub).data, rinfo, ci); */
+/*       } */
+/*     } */
+/*     break; */
+/*   case IDLN_INTERFACE: */
+/*     { */
+/*       IDL_tree sub; */
+/*       char *ifid; */
+
+/*       ifid = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0); */
+
+/*       for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) { */
+/*     IDL_tree cur; */
+
+/*     cur = IDL_LIST(sub).data; */
+
+/*     switch(IDL_NODE_TYPE(cur)) { */
+/*     case IDLN_OP_DCL: */
+/*       doskel(cur, rinfo, ifid, ci); */
+/*       break; */
+/*     case IDLN_ATTR_DCL: */
+/*       IDL_tree_warning(cur, IDL_WARNING1, "Attributes are not supperted\n"); */
+/* /\*           { *\/ */
+/* /\*             OIDL_Attr_Info *ai = cur->data; *\/ */
+/* /\*             IDL_tree curitem; *\/ */
+
+/* /\*             for(curitem = IDL_ATTR_DCL(cur).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) { *\/ */
+/* /\*               ai = IDL_LIST(curitem).data->data; *\/ */
+             
+/* /\*               doskel(ai->op1, rinfo, ifid, ci); *\/ */
+/* /\*               if(ai->op2) *\/ */
+/* /\*                 doskel(ai->op2, rinfo, ifid, ci); *\/ */
+/* /\*             } *\/ */
+/* /\*           } *\/ */
+/*       break; */
+/*     default: */
+/*       break; */
+/*     } */
+/*       } */
+/*       g_free(ifid); */
+/*     } */
+/*     break; */
+/*   default: */
+/*     break; */
+/*   } */
+/* } */
+
+/* static void */
+/* ch_output_itypes (IDL_tree tree, OIDL_C_Info *ci) */
+/* { */
+/*     static int num_methods = 0; */
+
+/*     if (!tree) */
+/*             return; */
+
+/*     switch(IDL_NODE_TYPE(tree)) { */
+/*     case IDLN_MODULE: */
+/*             ch_output_itypes (IDL_MODULE(tree).definition_list, ci); */
+/*             break; */
+/*     case IDLN_LIST: { */
+/*             IDL_tree sub; */
+/*             for (sub = tree; sub; sub = IDL_LIST(sub).next) */
+/*                     ch_output_itypes (IDL_LIST(sub).data, ci); */
+/*     } */
+/*     break; */
+/*     case IDLN_ATTR_DCL: { */
+/*             OIDL_Attr_Info *ai = tree->data; */
+
+/*             IDL_tree curitem; */
+      
+/*             for(curitem = IDL_ATTR_DCL(tree).simple_declarations; curitem; */
+/*                 curitem = IDL_LIST(curitem).next) { */
+/*                     ai = IDL_LIST(curitem).data->data; */
+       
+/*                     ch_output_itypes (ai->op1, ci); */
+/*                     if(ai->op2) */
+/*                             ch_output_itypes (ai->op2, ci); */
+/*             } */
+/*     } */
+/*     break; */
+
+/*     case IDLN_INTERFACE: { */
+/*             char  *id; */
+
+/*             id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS ( */
+/*                     IDL_INTERFACE (tree).ident), "_", 0); */
+
+/*             ch_output_itypes (IDL_INTERFACE(tree).body, ci); */
+      
+/*             fprintf (ci->fh, "#ifdef FORB_IDL_C_IMODULE_%s\n", */
+/*                      ci->c_base_name); */
+/*             fprintf (ci->fh, "static \n"); */
+/*             fprintf (ci->fh, "#else\n"); */
+/*             fprintf (ci->fh, "extern \n"); */
+/*             fprintf (ci->fh, "#endif\n"); */
+/*             fprintf (ci->fh, "Forb_IInterface %s__iinterface;\n", id); */
+
+/*             fprintf (ci->fh, "#define %s_IMETHODS_LEN %d\n", id, num_methods); */
+
+/*             if (num_methods == 0) */
+/*                     fprintf (ci->fh, "#define %s__imethods (Forb_IMethod*) NULL\n", id); */
+/*             else { */
+/*                     fprintf (ci->fh, "#ifdef FORB_IDL_C_IMODULE_%s\n", */
+/*                              ci->c_base_name); */
+/*                     fprintf (ci->fh, "static \n"); */
+/*                     fprintf (ci->fh, "#else\n"); */
+/*                     fprintf (ci->fh, "extern \n"); */
+/*                     fprintf (ci->fh, "#endif\n"); */
+/*                     fprintf (ci->fh, "Forb_IMethod %s__imethods[%s_IMETHODS_LEN];\n", id, id); */
+/*             } */
+
+
+/*             num_methods = 0; */
+
+/*             break; */
+/*     } */
+
+/*     case IDLN_OP_DCL: */
+/*             num_methods++; */
+/*             break; */
+/*     default: */
+/*             break; */
+/*     } */
+/* } */
diff --git a/src/forb/forb-idl/forb-idl-c-imodule.c b/src/forb/forb-idl/forb-idl-c-imodule.c
new file mode 100644 (file)
index 0000000..d4525ae
--- /dev/null
@@ -0,0 +1,235 @@
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+#include "forb_config.h"
+
+static void
+ci_build_interfaces (OIDL_C_Info *ci,
+                    IDL_tree     tree)
+{
+       if (!tree)
+               return;
+
+       switch (IDL_NODE_TYPE (tree)) {
+       case IDLN_MODULE:
+               ci_build_interfaces (
+                       ci, IDL_MODULE (tree).definition_list);
+               break;
+       case IDLN_LIST: {
+               IDL_tree sub;
+               for (sub = tree; sub; sub = IDL_LIST (sub).next)
+                       ci_build_interfaces (
+                               ci, IDL_LIST (sub).data);
+               break;
+       }
+       case IDLN_INTERFACE: {
+               char *id;
+
+               id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (
+                       IDL_INTERFACE (tree).ident), "_", 0);
+
+               fprintf (ci->fh, "\t&%s__iinterface,\n", id);
+
+               g_free (id);
+
+               ci_build_interfaces (
+                       ci, IDL_INTERFACE(tree).body);
+               break;
+       }
+       default:
+               break;
+       }
+}
+
+static void
+ci_build_types (OIDL_C_Info *ci,
+               IDL_tree     tree,
+               guint       *count)
+{
+       if (!tree)
+               return;
+
+       switch (IDL_NODE_TYPE (tree)) {
+       case IDLN_MODULE:
+               ci_build_types (
+                       ci, IDL_MODULE (tree).definition_list, count);
+               break;
+       case IDLN_LIST: {
+               IDL_tree sub;
+               for (sub = tree; sub; sub = IDL_LIST (sub).next)
+                       ci_build_types (
+                               ci, IDL_LIST (sub).data, count);
+               break;
+       }
+       case IDLN_INTERFACE:
+               ci_build_types (
+                       ci, IDL_INTERFACE(tree).body, count);
+               break;
+       case IDLN_TYPE_DCL: {
+           IDL_tree sub;
+           for (sub = IDL_TYPE_DCL (tree).dcls; sub; sub = IDL_LIST (sub).next) {
+               IDL_tree ent = IDL_LIST (sub).data;
+               gchar *id;
+
+               id = forb_cbe_get_typespec_str (ent);
+
+               fprintf (ci->fh, "\tTC_%s,\n", id);
+               (*count)++;
+
+               g_free (id);
+           }
+
+           break;
+       }
+       case IDLN_TYPE_STRUCT: {
+               gchar *id;
+               IDL_tree l;
+
+               id = forb_cbe_get_typespec_str (tree);
+
+               fprintf (ci->fh, "\tTC_%s,\n", id);
+               (*count)++;
+
+               g_free (id);
+
+               /* check for nested structs/enums */
+               for (l = IDL_TYPE_STRUCT (tree).member_list; l; l = IDL_LIST (l).next) {
+                       IDL_tree dcl;
+
+                       g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_MEMBER);
+                       dcl = IDL_MEMBER (IDL_LIST (l).data).type_spec;
+
+                       /* skip straight declarations */
+                       if (IDL_NODE_TYPE(dcl) == IDLN_TYPE_STRUCT ||
+                           IDL_NODE_TYPE(dcl) == IDLN_TYPE_UNION ||
+                           IDL_NODE_TYPE(dcl) == IDLN_TYPE_ENUM)
+                               ci_build_types (ci, dcl, count);
+               }
+               break;
+       };
+       case IDLN_TYPE_UNION: {
+               gchar *id;
+               IDL_tree l;
+
+               id = forb_cbe_get_typespec_str (tree);
+
+               fprintf (ci->fh, "\tTC_%s,\n", id);
+               (*count)++;
+
+               g_free (id);
+
+               /* if discriminator is an enum, register it */
+               if (IDL_NODE_TYPE (IDL_TYPE_UNION (tree).switch_type_spec) == IDLN_TYPE_ENUM)
+                       ci_build_types (
+                               ci, IDL_TYPE_UNION (tree).switch_type_spec, count);
+
+               /* check for nested structs/enums */
+               for (l = IDL_TYPE_UNION (tree).switch_body; l; l = IDL_LIST (l).next) {
+                       IDL_tree dcl;
+
+                       g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_CASE_STMT);
+                       dcl = IDL_MEMBER (
+                                IDL_CASE_STMT (IDL_LIST (l).data).element_spec).type_spec;
+
+                       if (IDL_NODE_TYPE(dcl) == IDLN_TYPE_STRUCT ||
+                           IDL_NODE_TYPE(dcl) == IDLN_TYPE_UNION ||
+                           IDL_NODE_TYPE(dcl) == IDLN_TYPE_ENUM)
+                               ci_build_types (ci, dcl, count);
+               }
+               break;
+       }
+       case IDLN_EXCEPT_DCL: {
+               gchar *id;
+               IDL_tree l;
+
+               id = forb_cbe_get_typespec_str (tree);
+
+               fprintf (ci->fh, "\tTC_%s,\n", id);
+               (*count)++;
+
+               g_free (id);
+
+               /* check for nested structs/enums */
+               for (l = IDL_EXCEPT_DCL (tree).members; l; l = IDL_LIST (l).next) {
+                       IDL_tree dcl;
+
+                       g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_MEMBER);
+                       dcl = IDL_MEMBER (IDL_LIST (l).data).type_spec;
+
+                       /* skip straight declarations */
+                       if (IDL_NODE_TYPE(dcl) == IDLN_TYPE_STRUCT ||
+                           IDL_NODE_TYPE(dcl) == IDLN_TYPE_UNION ||
+                           IDL_NODE_TYPE(dcl) == IDLN_TYPE_ENUM)
+                               ci_build_types (ci, dcl, count);
+               }
+               break;
+       }
+       case IDLN_TYPE_INTEGER:
+       case IDLN_TYPE_ANY:
+       case IDLN_TYPE_STRING:
+       case IDLN_TYPE_WIDE_STRING:
+       case IDLN_TYPE_CHAR:
+       case IDLN_TYPE_WIDE_CHAR:
+       case IDLN_TYPE_FLOAT:
+       case IDLN_TYPE_BOOLEAN:
+       case IDLN_TYPE_OCTET:
+       case IDLN_TYPE_SEQUENCE:
+       case IDLN_TYPE_ENUM:
+       case IDLN_IDENT:
+       case IDLN_FORWARD_DCL:
+       case IDLN_TYPE_OBJECT: {
+               gchar *id;
+
+               id = forb_cbe_get_typespec_str (tree);
+
+               fprintf (ci->fh, "\tTC_%s,\n", id);
+               (*count)++;
+
+               g_free (id);
+
+               break;
+       }
+       default:
+               break;
+       }
+}
+
+void
+forb_idl_output_c_imodule (IDL_tree       tree,
+                           OIDL_Run_Info *rinfo,
+                           OIDL_C_Info   *ci)
+{
+       guint count;
+
+       fprintf (ci->fh, OIDL_C_WARNING);
+       fprintf (ci->fh, "#include <string.h>\n");
+       fprintf (ci->fh, "#define FORB_IDL_C_IMODULE_%s\n\n",ci->c_base_name);
+
+       fprintf (ci->fh, "#include \"%s-common.c\"\n\n", ci->base_name);
+
+       fprintf (ci->fh, "#include <forb/orb-core/forb-small.h>\n\n");
+
+       fprintf (ci->fh, "static CORBA_TypeCode %s__itypes[] = {\n",
+                ci->c_base_name);
+
+       count = 0;
+       ci_build_types (ci, tree, &count);
+
+       fprintf (ci->fh, "\tNULL\n};\n\n");
+
+       fprintf (ci->fh, "static Forb_IInterface *%s__iinterfaces[] = {\n",
+                ci->c_base_name);
+
+       ci_build_interfaces (ci, tree);
+
+       fprintf (ci->fh, "\tNULL\n};\n");
+
+       fprintf (ci->fh, "Forb_IModule forb_imodule_data = {\n");
+       fprintf (ci->fh, "   %d,\n", FORB_CONFIG_SERIAL);
+       fprintf (ci->fh, "   %s__iinterfaces,\n", ci->c_base_name);
+       fprintf (ci->fh, " { %u, %u, %s__itypes, FALSE }\n",
+                count, count, ci->c_base_name);
+       fprintf (ci->fh, "};\n\n");
+}
diff --git a/src/forb/forb-idl/forb-idl-c-skelimpl.c b/src/forb/forb-idl/forb-idl-c-skelimpl.c
new file mode 100644 (file)
index 0000000..923b12c
--- /dev/null
@@ -0,0 +1,603 @@
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+/* This file copied from the old IDL compiler forb-c-skelimpl.c, with minimal changes. */
+
+static void forb_cbe_write_skelimpl(FILE *outfile, IDL_tree tree, const char *hdrname);
+
+void
+forb_idl_output_c_skelimpl(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+       forb_cbe_write_skelimpl(ci->fh, tree, ci->base_name);
+}
+
+#include <ctype.h>
+#include <errno.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* Abbreviations used here:
+   "cbe" stands for "C backend"
+   "hdr" -> "header" (duh :)
+   "of" -> "output file"
+   "ns" -> "name space"
+*/
+
+typedef struct {
+       FILE *of;
+       IDL_tree tree;
+       enum { PASS_SERVANTS, PASS_PROTOS, PASS_EPVS, PASS_VEPVS,
+              PASS_IMPLSTUBS, PASS_LAST } pass;
+} CBESkelImplInfo;
+
+static const char *passnames[] = {
+       "App-specific servant structures",
+       "Implementation stub prototypes",
+       "epv structures",
+       "vepv structures",
+       "Stub implementations",
+       "Boohoo!"
+};
+
+static void forb_cbe_ski_process_piece(CBESkelImplInfo *ski);
+static void cbe_ski_do_list(CBESkelImplInfo *ski);
+static void cbe_ski_do_inherited_attr_dcl(CBESkelImplInfo *ski, IDL_tree current_interface);
+static void cbe_ski_do_attr_dcl(CBESkelImplInfo *ski);
+static void cbe_ski_do_inherited_op_dcl(CBESkelImplInfo *ski, IDL_tree current_interface);
+static void cbe_ski_do_op_dcl(CBESkelImplInfo *ski);
+static void cbe_ski_do_param_dcl(CBESkelImplInfo *ski);
+static void cbe_ski_do_interface(CBESkelImplInfo *ski);
+static void cbe_ski_do_module(CBESkelImplInfo *ski);
+
+static void
+forb_cbe_write_skelimpl(FILE *outfile, IDL_tree tree, const char *hdrname)
+{
+       CBESkelImplInfo ski = {NULL, NULL, PASS_SERVANTS};
+
+       ski.of = outfile;
+       ski.tree = tree;
+
+       g_return_if_fail(IDL_NODE_TYPE(tree) == IDLN_LIST);
+
+       fprintf(outfile, "/* This is a template file generated by command */\n");
+       fprintf(outfile, "/* forb-idl-2 --skeleton-impl %s.idl */\n", hdrname);
+       fprintf(outfile, "/* User must edit this file, inserting servant  */\n");
+       fprintf(outfile, "/* specific code between markers. */\n\n");
+
+       fprintf(outfile, "#include \"%s.h\"\n", hdrname);
+
+       for(ski.pass = PASS_SERVANTS; ski.pass < PASS_LAST; ski.pass++) {
+               fprintf(ski.of, "\n/*** %s ***/\n\n", passnames[ski.pass]);
+               forb_cbe_ski_process_piece(&ski);
+       }
+}
+
+static void
+forb_cbe_ski_process_piece(CBESkelImplInfo *ski)
+{
+       /* I'm not implementing this as an array of function pointers
+          because we may want to do special logic for particular cases in
+          the future. Hope this is clear enough. -ECL */
+
+       switch(IDL_NODE_TYPE(ski->tree)) {
+       case IDLN_ATTR_DCL:
+               cbe_ski_do_attr_dcl(ski);
+               break;
+       case IDLN_INTERFACE:
+               cbe_ski_do_interface(ski);
+               break;
+       case IDLN_LIST:
+               cbe_ski_do_list(ski);
+               break;
+       case IDLN_MODULE:
+               cbe_ski_do_module(ski);
+               break;
+       case IDLN_OP_DCL:
+               cbe_ski_do_op_dcl(ski);
+               break;
+       case IDLN_PARAM_DCL:
+               cbe_ski_do_param_dcl(ski);
+               break;
+       default:
+               break;
+       }
+}
+
+static void
+cbe_ski_do_module(CBESkelImplInfo *ski)
+{
+       CBESkelImplInfo subski = *ski;
+       subski.tree = IDL_MODULE(ski->tree).definition_list;
+       cbe_ski_do_list(&subski);
+}
+
+/* Returns 1 if the previous character written to f  */
+/* was '\n', 0 otherwise. */
+static inline unsigned char 
+prev_char_is_nl(FILE *f)
+{
+        char c;
+       long pos;
+       size_t count;
+        unsigned char retv = 0;
+
+       pos = ftell(f);
+       if (pos < sizeof(char)) 
+               return 0; /* beginning of file */
+
+        if (fseek(f, (-1)*sizeof(char), SEEK_CUR)) 
+               goto out;
+
+       count = fread((void*)&c, sizeof(char), 1, f);
+        if (sizeof(char) == count) 
+               retv = ('\n' == c) ? 1 : 0;
+       
+out:
+       fseek(f, pos, SEEK_SET);
+        return retv;
+}
+
+static void
+cbe_ski_do_list(CBESkelImplInfo *ski)
+{
+       CBESkelImplInfo subski = *ski;
+       IDL_tree curitem;
+
+       for(curitem = ski->tree; curitem; curitem = IDL_LIST(curitem).next) {
+               subski.tree = IDL_LIST(curitem).data;
+               forb_cbe_ski_process_piece(&subski);
+               if(!prev_char_is_nl(ski->of))
+                       fprintf(ski->of, "\n");
+       }
+}
+
+static void 
+cbe_ski_do_attr_dcl_internal(CBESkelImplInfo *ski, IDL_tree current_interface, gboolean inherited)
+{
+       IDL_tree curop, curitem;
+       GString *attrname = g_string_new(NULL);
+       CBESkelImplInfo subski = *ski;
+
+       if(ski->pass == PASS_SERVANTS) {
+               for(curitem = IDL_ATTR_DCL(ski->tree).simple_declarations; curitem;
+                   curitem = IDL_LIST(curitem).next) {
+                       forb_cbe_write_typespec(ski->of, IDL_ATTR_DCL(ski->tree).param_type_spec);
+                       fprintf(ski->of, " attr_%s;\n", IDL_IDENT(IDL_LIST(curitem).data).str);
+               }
+       }
+
+       for(curitem = IDL_ATTR_DCL(ski->tree).simple_declarations;
+           curitem; curitem = IDL_LIST(curitem).next) {
+
+               /* Fake the attribute get/set methods as operation declarations */
+               IDL_tree ident, ns_data_save;
+               int i;
+
+               for (i = 0; i < 2; ++i) {
+
+                       if (i && IDL_ATTR_DCL(ski->tree).f_readonly)
+                               break;
+                       /* Output the operation on this attribute */
+                       g_string_printf(attrname, i ? "_set_%s" : "_get_%s",
+                                       IDL_IDENT(IDL_LIST(curitem).data).str);
+                       ident = IDL_ident_new(g_strdup(attrname->str));
+           
+                       /* Tell the ident where our namespace node is, and request a return value
+                          if this is the _get operation */
+                       IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(IDL_LIST(curitem).data);
+                       curop = IDL_op_dcl_new(0, i == 0 ?
+                                              IDL_ATTR_DCL(ski->tree).param_type_spec : NULL,
+                                              ident, NULL, NULL, NULL);
+           
+                       curop->up = ski->tree->up;
+                       subski.tree = curop;
+           
+                       /* Save the namespace ident (IDL_GENTREE data) reference, assign
+                          back to the temporary tree, output the operation, then restore
+                          the namespace ident link */
+                       ns_data_save = IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data;
+                       IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data = ident;
+
+                       if (i) {
+                               /* The set routine also needs the value, so we
+                                  temporarily add that to the operation
+                                  declaration */
+                               IDL_OP_DCL(curop).parameter_dcls = IDL_list_new(
+                                       IDL_param_dcl_new(IDL_PARAM_IN,
+                                                         IDL_ATTR_DCL(ski->tree).param_type_spec,
+                                                         IDL_ident_new(g_strdup("value"))));
+                       }
+           
+                       if(inherited==TRUE)
+                               cbe_ski_do_inherited_op_dcl(&subski, current_interface);
+                       else
+                               forb_cbe_ski_process_piece(&subski);
+
+                       /* Restore the fake link to the original in the namespace */
+                       IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data = ns_data_save;
+
+                       if (i) {
+                               /* Free only what we've created for the fake node, so remove 
+                                  the attribute node element and then free the rest */
+                               IDL_PARAM_DCL(IDL_LIST(
+                                                     IDL_OP_DCL(curop).parameter_dcls).data).param_type_spec = NULL;
+                       }
+           
+                       /* Remove what we've "borrowed" from ATTR_DCL from the
+                          fake curop node then free the rest */
+                       IDL_OP_DCL(curop).op_type_spec = NULL;
+                       IDL_tree_free(curop);
+               }
+       }
+
+       g_string_free(attrname, TRUE);
+}
+
+static void 
+cbe_ski_do_attr_dcl(CBESkelImplInfo *ski)
+{
+       cbe_ski_do_attr_dcl_internal(ski, NULL, FALSE);
+}
+
+void
+cbe_ski_do_inherited_attr_dcl(CBESkelImplInfo *ski, IDL_tree current_interface)
+{
+       cbe_ski_do_attr_dcl_internal(ski, current_interface, TRUE);
+}
+
+static void
+cbe_ski_do_op_dcl(CBESkelImplInfo *ski)
+{
+       /* If you fix anything here, please also fix it in
+          cbe_ski_do_inherited_op_dcl(), which is almost a
+          cut-and-paste of this routine */
+
+       char *id, *id2;
+       IDL_tree curitem, op;
+       int level;
+       CBESkelImplInfo subski = *ski;
+
+       switch(ski->pass) {
+       case PASS_PROTOS:
+       case PASS_IMPLSTUBS:
+               curitem = IDL_get_parent_node(ski->tree, IDLN_INTERFACE, &level);
+               g_assert(curitem);
+
+               id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(ski->tree).ident), "_", 0);    
+               id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(curitem).ident), "_", 0);
+
+               /* protect with #ifdef block  */
+               if(PASS_PROTOS == ski->pass) 
+                       fprintf(ski->of, "#if !defined(_decl_impl_");
+               else
+                       fprintf(ski->of, "#if !defined(_impl_");
+               fprintf(ski->of, "%s_)\n", id);
+
+               if(PASS_PROTOS == ski->pass) 
+                       fprintf(ski->of, "#define _decl_impl_");
+               else
+                       fprintf(ski->of, "#define _impl_");
+               fprintf(ski->of, "%s_ 1\n", id);
+
+               fprintf(ski->of, "static ");
+               forb_cbe_write_param_typespec(ski->of, ski->tree);    
+               fprintf(ski->of, "\nimpl_%s(impl_POA_%s *servant,\n", id, id2);
+               g_free(id); g_free(id2);
+    
+               op = ski->tree;
+               for(curitem = IDL_OP_DCL(ski->tree).parameter_dcls;
+                   curitem; curitem = IDL_LIST(curitem).next) {
+                       subski.tree = IDL_LIST(curitem).data;
+                       forb_cbe_ski_process_piece(&subski);
+               }
+
+               if(IDL_OP_DCL(op).context_expr)
+                       fprintf(ski->of, "CORBA_Context ctx,\n");
+
+               fprintf(ski->of, "CORBA_Environment *ev)");
+               if(ski->pass == PASS_IMPLSTUBS) {
+                       fprintf(ski->of, "\n{\n");
+                       if(IDL_OP_DCL(op).op_type_spec) {
+                               forb_cbe_write_param_typespec(ski->of, ski->tree);
+                               fprintf(ski->of, " retval;\n");
+                               fprintf(ski->of, " /* ------   insert method code here   ------ */\n");
+                               fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
+                               fprintf(ski->of, "\nreturn retval;\n");
+                       }
+                       else
+                       {       
+                               fprintf(ski->of, " /* ------   insert method code here   ------ */\n");
+                               fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
+                       }
+                       fprintf(ski->of, "}\n");
+               } else /* PASS_PROTOS */
+                       fprintf(ski->of, ";\n");
+
+               fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+               break; /* End PASS_PROTOS | PASS_IMPLSTUBS */
+       case PASS_EPVS:
+               id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(ski->tree).ident), "_", 0);
+               fprintf(ski->of, "(gpointer)&impl_%s,\n", id);
+               g_free(id);
+               break;
+       default:
+               break;
+       }
+}
+
+static void
+cbe_ski_do_inherited_op_dcl(CBESkelImplInfo *ski, IDL_tree current_interface)
+{
+       char *id, *id2;
+       IDL_tree ident, curitem, intf, op;
+       int level;
+       CBESkelImplInfo subski = *ski;
+
+       id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(current_interface).ident), "_", 0);
+       intf = IDL_get_parent_node(ski->tree, IDLN_INTERFACE, NULL);
+       id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(intf).ident), "_", 0);
+
+       ident=IDL_OP_DCL(ski->tree).ident;
+       g_assert(ident);
+
+       switch(ski->pass) {
+       case PASS_PROTOS:
+       case PASS_IMPLSTUBS:
+               curitem = IDL_get_parent_node(ski->tree, IDLN_INTERFACE, &level);
+               g_assert(curitem);
+
+               /* protect with #ifdef block  */
+               if(PASS_PROTOS == ski->pass) 
+                       fprintf(ski->of, "#if !defined(_decl_impl_");
+               else
+                       fprintf(ski->of, "#if !defined(_impl_");
+               fprintf(ski->of, "%s_%s_)\n", id, IDL_IDENT(ident).str);
+
+               if(PASS_PROTOS == ski->pass) 
+                       fprintf(ski->of, "#define _decl_impl_");
+               else
+                       fprintf(ski->of, "#define _impl_");
+               fprintf(ski->of, "%s_%s_ 1\n", id, IDL_IDENT(ident).str);
+
+               fprintf(ski->of, "static ");
+               forb_cbe_write_param_typespec(ski->of, ski->tree);
+               fprintf(ski->of, "\nimpl_%s_%s(impl_POA_%s *servant,\n", id, IDL_IDENT(ident).str, id);
+    
+               op = ski->tree;
+               for(curitem = IDL_OP_DCL(ski->tree).parameter_dcls;
+                   curitem; curitem = IDL_LIST(curitem).next) {
+                       subski.tree = IDL_LIST(curitem).data;
+                       forb_cbe_ski_process_piece(&subski);
+               }
+
+               if(IDL_OP_DCL(op).context_expr)
+                       fprintf(ski->of, "CORBA_Context ctx,\n");
+
+               fprintf(ski->of, "CORBA_Environment *ev)");
+               if(ski->pass == PASS_IMPLSTUBS) {
+                       fprintf(ski->of, "\n{\n");
+                       if(IDL_OP_DCL(op).op_type_spec) {
+                               forb_cbe_write_param_typespec(ski->of, ski->tree);
+                               fprintf(ski->of, " retval;\n");
+                               fprintf(ski->of, " /* ------   insert method code here   ------ */\n");
+                               fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
+                               fprintf(ski->of, "\nreturn retval;\n");
+                       }
+                       else
+                       {       
+                               fprintf(ski->of, " /* ------   insert method code here   ------ */\n");
+                               fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
+                       }
+                       fprintf(ski->of, "}\n");
+               } else /* PASS_PROTOS */
+                       fprintf(ski->of, ";\n");
+
+               fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+               break; /* End PASS_PROTOS | PASS_IMPLSTUBS */
+       case PASS_EPVS:
+               ident=IDL_OP_DCL(ski->tree).ident;
+               g_assert(ident);
+
+               fprintf(ski->of, "(gpointer)&impl_%s_%s,\n", id, IDL_IDENT(ident).str);
+       default:
+               break;
+       }
+
+       g_free(id);
+       g_free(id2);
+}
+
+static void
+cbe_ski_do_param_dcl(CBESkelImplInfo *ski)
+{
+       forb_cbe_write_param_typespec(ski->of, ski->tree);
+       fprintf(ski->of, " %s,\n", IDL_IDENT(IDL_PARAM_DCL(ski->tree).simple_declarator).str);
+}
+
+static void
+cbe_ski_do_interface_vepv_entry(IDL_tree interface, CBESkelImplInfo *ski)
+{
+       char *id, *inherit_id;
+
+       if(interface==ski->tree) {
+               id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0);
+               fprintf(ski->of, "&impl_%s_epv,\n", id);
+               g_free(id);
+               return;
+       }
+
+       id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0);
+       inherit_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(interface).ident),
+                                            "_", 0);
+       fprintf(ski->of, "&impl_%s_%s_epv,\n", id, inherit_id);
+
+       g_free(id);
+       g_free(inherit_id);
+}
+
+static void
+cbe_ski_do_inherited_methods(IDL_tree interface, CBESkelImplInfo *ski)
+{
+       CBESkelImplInfo subski= *ski;
+       IDL_tree curitem;
+       char *id = NULL, *inherit_id = NULL; /* Quiet gcc */
+
+       if(interface==ski->tree)
+               return;
+
+       if(ski->pass==PASS_EPVS) {
+               id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident),
+                                            "_", 0);
+               inherit_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(interface).ident),
+                                                    "_", 0);
+               /* protect with #ifdef block  */
+               fprintf(ski->of, "#if !defined(_impl_%s_%s_epv_)\n", id, inherit_id);
+               fprintf(ski->of, "#define _impl_%s_%s_epv_ 1\n", id, inherit_id);
+               fprintf(ski->of, "static POA_%s__epv impl_%s_%s_epv = {\nNULL, /* _private */\n", inherit_id, id, inherit_id);
+       }
+
+       for(curitem = IDL_INTERFACE(interface).body; curitem; curitem=IDL_LIST(curitem).next) {
+               subski.tree=IDL_LIST(curitem).data;
+
+               switch(IDL_NODE_TYPE(IDL_LIST(curitem).data)) {
+               case IDLN_OP_DCL:
+                       cbe_ski_do_inherited_op_dcl(&subski, ski->tree);
+                       break;
+               case IDLN_ATTR_DCL:
+                       cbe_ski_do_inherited_attr_dcl(&subski, ski->tree);
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if(ski->pass==PASS_EPVS) {
+               fprintf(ski->of, "};\n"); 
+               fprintf(ski->of, "#endif\n"); /* end of protective #ifdef block */
+
+               g_free(id);
+               g_free(inherit_id);
+       }
+}
+
+static void
+cbe_ski_do_interface(CBESkelImplInfo *ski)
+{
+       char *id;
+       CBESkelImplInfo subski = *ski;
+
+       id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0);
+
+       switch(ski->pass) {
+       case PASS_SERVANTS:
+               /* protect with #ifdef block  */
+               fprintf(ski->of, "#if !defined(_typedef_impl_POA_%s_)\n", id);
+               fprintf(ski->of, "#define _typedef_impl_POA_%s_ 1\n", id);
+
+               fprintf(ski->of, "typedef struct {\nPOA_%s servant;\nPortableServer_POA poa;\n", id);
+               subski.tree = IDL_INTERFACE(ski->tree).body;
+               cbe_ski_do_list(&subski);
+               IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);
+               fprintf(ski->of, "   /* ------ add private attributes here ------ */\n");
+               fprintf(ski->of, "   /* ------ ---------- end ------------ ------ */\n");
+               fprintf(ski->of, "} impl_POA_%s;\n", id);
+
+               fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+               break;
+       case PASS_EPVS:
+               /* protect with #ifdef block  */
+               fprintf(ski->of, "#if !defined(_impl_%s_base_epv_)\n", id);
+               fprintf(ski->of, "#define _impl_%s_base_epv_ 1\n", id);
+               fprintf(ski->of, "static PortableServer_ServantBase__epv impl_%s_base_epv = {\n", id);
+               fprintf(ski->of, "NULL,             /* _private data */\n");
+               fprintf(ski->of, "(gpointer) & impl_%s__destroy, /* finalize routine */\n", id);
+               fprintf(ski->of, "NULL,             /* default_POA routine */\n");
+               fprintf(ski->of, "};\n");
+               fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+
+               /* protect with #ifdef block  */
+               fprintf(ski->of, "#if !defined(_impl_%s_epv_)\n", id);
+               fprintf(ski->of, "#define _impl_%s_epv_ 1\n", id);
+               fprintf(ski->of, "static POA_%s__epv impl_%s_epv = {\nNULL, /* _private */\n", id, id);
+               subski.tree = IDL_INTERFACE(ski->tree).body;
+               cbe_ski_do_list(&subski);
+               fprintf(ski->of, "};\n");
+               fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+
+               IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);
+               break;
+       case PASS_VEPVS:
+               /* protect with #ifdef block  */
+               fprintf(ski->of, "#if !defined(_impl_%s_vepv_)\n", id);
+               fprintf(ski->of, "#define _impl_%s_vepv_ 1\n", id);
+
+               fprintf(ski->of, "static POA_%s__vepv impl_%s_vepv = {\n", id, id);
+               fprintf(ski->of, "&impl_%s_base_epv,\n", id);
+               IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_interface_vepv_entry, ski);
+               fprintf(ski->of, "};\n");
+
+               fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+               break;
+       case PASS_IMPLSTUBS:
+               /* protect __create with #ifdef block  */
+               fprintf(ski->of, "#if !defined(_impl_%s__create_)\n", id);
+               fprintf(ski->of, "#define _impl_%s__create_ 1\n", id);
+               fprintf(ski->of, "static %s impl_%s__create(PortableServer_POA poa, CORBA_Environment *ev)\n", id, id);
+               fprintf(ski->of, "{\n%s retval;\nimpl_POA_%s *newservant;\nPortableServer_ObjectId *objid;\n\n", id, id);
+               fprintf(ski->of, "newservant = g_new0(impl_POA_%s, 1);\n", id);
+               fprintf(ski->of, "newservant->servant.vepv = &impl_%s_vepv;\n", id);
+               fprintf(ski->of, "newservant->poa = (PortableServer_POA) CORBA_Object_duplicate((CORBA_Object)poa, ev);\n");
+               fprintf(ski->of, "POA_%s__init((PortableServer_Servant)newservant, ev);\n", id);
+               fprintf(ski->of, "   /* Before servant is going to be activated all\n");
+               fprintf(ski->of, "    * private attributes must be initialized.  */\n"); 
+               fprintf(ski->of, "\n");
+               fprintf(ski->of, "   /* ------ init private attributes here ------ */\n");
+               fprintf(ski->of, "   /* ------ ---------- end ------------- ------ */\n");
+               fprintf(ski->of, "\n");
+               fprintf(ski->of, "objid = PortableServer_POA_activate_object(poa, newservant, ev);\n");
+               fprintf(ski->of, "CORBA_free(objid);\n");
+               fprintf(ski->of, "retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);\n");
+               fprintf(ski->of, "\nreturn retval;\n}\n");
+               fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+
+               /* protect __destroy with #ifdef block  */
+               fprintf(ski->of, "#if !defined(_impl_%s__destroy_)\n", id);
+               fprintf(ski->of, "#define _impl_%s__destroy_ 1\n", id);
+               fprintf(ski->of, "static void\nimpl_%s__destroy(impl_POA_%s *servant, CORBA_Environment *ev)\n{\n", id, id);
+               fprintf(ski->of, "    CORBA_Object_release ((CORBA_Object) servant->poa, ev);\n\n");
+               fprintf(ski->of, "    /* No further remote method calls are delegated to \n");
+               fprintf(ski->of, "    * servant and you may free your private attributes. */\n");
+               fprintf(ski->of, "   /* ------ free private attributes here ------ */\n");
+               fprintf(ski->of, "   /* ------ ---------- end ------------- ------ */\n");
+               fprintf(ski->of, "\nPOA_%s__fini((PortableServer_Servant)servant, ev);\n", id);
+               fprintf(ski->of, "\ng_free (servant);\n");
+               fprintf(ski->of, "}\n");
+               fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+
+               subski.tree = IDL_INTERFACE(ski->tree).body;
+               cbe_ski_do_list(&subski);
+               IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);
+               break;
+       case PASS_PROTOS:
+               /* protect __destroy declaration with #ifdef block  */
+               fprintf(ski->of, "#if !defined(_decl_impl_%s__destroy_)\n", id);
+               fprintf(ski->of, "#define _decl_impl_%s__destroy_ 1\n", id);
+               fprintf(ski->of, "static void impl_%s__destroy(impl_POA_%s *servant,\nCORBA_Environment *ev);\n", id, id);
+               fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+
+               subski.tree = IDL_INTERFACE(ski->tree).body;
+               cbe_ski_do_list(&subski);
+               IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);
+               break;
+       default:
+               break;
+       }
+
+       g_free(id);
+}
diff --git a/src/forb/forb-idl/forb-idl-c-skels.c b/src/forb/forb-idl/forb-idl-c-skels.c
new file mode 100644 (file)
index 0000000..1d35338
--- /dev/null
@@ -0,0 +1,542 @@
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+
+typedef struct {
+       OIDL_C_Info *ci;
+       GSList      *oplist;
+       int          curlevel;
+} CBESkelInterfaceTraverseInfo;
+
+typedef struct {
+       char     *iface_id;
+       char     *opname;
+       IDL_tree  op;
+       int       idx;
+} CBESkelOpInfo;
+
+static void cbe_skel_do_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+
+static void
+ck_output_poastuff(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+  if( !tree || (tree->declspec & IDLF_DECLSPEC_PIDL)!=0 ) 
+    return;
+
+  switch(IDL_NODE_TYPE(tree)) {
+  case IDLN_MODULE:
+    ck_output_poastuff(IDL_MODULE(tree).definition_list, rinfo, ci);
+    break;
+  case IDLN_LIST:
+    {
+      IDL_tree sub;
+      for(sub = tree; sub; sub = IDL_LIST(sub).next) {
+       ck_output_poastuff(IDL_LIST(sub).data, rinfo, ci);
+      }
+    }
+    break;
+  case IDLN_INTERFACE:
+    cbe_skel_do_interface(tree, rinfo, ci);
+    break;
+  default:
+    break;
+  }
+}
+
+/* static gint */
+/* cbe_skel_compare_op_dcls(CBESkelOpInfo *op1, CBESkelOpInfo *op2) */
+/* { */
+/*   return strcmp(op1->opname, op2->opname); */
+/* } */
+
+/* static void */
+/* cbe_skel_free_op_info(CBESkelOpInfo *op) */
+/* { */
+/*   g_free(op->opname); */
+/*   g_free(op->iface_id); */
+/*   g_free(op); */
+/* } */
+
+/* static void */
+/* cbe_skel_interface_add_relayer (IDL_tree intf, CBESkelInterfaceTraverseInfo *iti) */
+/* { */
+/*   CBESkelOpInfo *newopi; */
+/*   IDL_tree curitem, curdcl, curattr, curattrdcl; */
+/*   char *iface_id; */
+/*   int   idx = 0; */
+
+/*   iface_id = */
+/*     IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(intf).ident), */
+/*                         "_", 0); */
+
+/*   for(curitem = IDL_INTERFACE(intf).body; curitem; */
+/*       curitem = IDL_LIST(curitem).next) { */
+/*     curdcl = IDL_LIST(curitem).data; */
+
+/*     switch(IDL_NODE_TYPE(curdcl)) { */
+/*     case IDLN_OP_DCL: */
+/*       newopi = g_new0(CBESkelOpInfo, 1); */
+/*       newopi->iface_id = g_strdup(iface_id); */
+/*       newopi->opname = g_strdup(IDL_IDENT(IDL_OP_DCL(curdcl).ident).str); */
+/*       newopi->idx = idx++; */
+/*       iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, */
+/*                                       (GCompareFunc)cbe_skel_compare_op_dcls); */
+/*       break; */
+/*     case IDLN_ATTR_DCL: */
+/*       for(curattr = IDL_ATTR_DCL(curdcl).simple_declarations; */
+/*       curattr; curattr = IDL_LIST(curattr).next) { */
+/*     curattrdcl = IDL_LIST(curattr).data; */
+
+/*     newopi = g_new0(CBESkelOpInfo, 1); */
+/*     newopi->iface_id = g_strdup(iface_id); */
+/*     newopi->opname = g_strdup_printf("_get_%s", IDL_IDENT(curattrdcl).str); */
+/*     newopi->idx = idx++; */
+/*     iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, */
+/*                                         (GCompareFunc)cbe_skel_compare_op_dcls); */
+/*     if(!IDL_ATTR_DCL(curdcl).f_readonly) { */
+/*       newopi = g_new0(CBESkelOpInfo, 1); */
+/*       newopi->iface_id = g_strdup(iface_id); */
+/*       newopi->opname = g_strdup_printf("_set_%s", IDL_IDENT(curattrdcl).str); */
+/*       newopi->idx = idx++; */
+/*       iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, */
+/*                                           (GCompareFunc)cbe_skel_compare_op_dcls); */
+/*     } */
+/*       } */
+/*       break; */
+/*     default: */
+/*       break; */
+/*     } */
+/*   } */
+
+/*   g_free(iface_id); */
+/* } */
+
+/* static void */
+/* cbe_skel_interface_print_relayers(const CBESkelInterfaceTraverseInfo *iti) */
+/* { */
+/*   CBESkelInterfaceTraverseInfo subiti = *iti; */
+/*   GSList *curnode; */
+/*   CBESkelOpInfo *opi; */
+/*   char curchar; */
+
+/*   curnode = iti->oplist; */
+/*   subiti.curlevel = iti->curlevel+1; */
+/*   fprintf(iti->ci->fh, "switch(opname[%d]) {\n", iti->curlevel); */
+/*   while(curnode) { */
+/*     opi = (CBESkelOpInfo *)curnode->data; */
+/*     if(iti->curlevel > strlen(opi->opname)) { */
+/*       curnode = g_slist_next(curnode); */
+/*       continue; */
+/*     } */
+/*     curchar = opi->opname[iti->curlevel]; */
+/*     if(curchar) */
+/*       fprintf(iti->ci->fh, "case '%c':\n", curchar); */
+/*     else */
+/*       fprintf(iti->ci->fh, "case '\\0':\n"); */
+/*     subiti.oplist = NULL; */
+/*     while(curnode && ((CBESkelOpInfo *)curnode->data)->opname[iti->curlevel] */
+/*       == curchar) { */
+/*       subiti.oplist = g_slist_append(subiti.oplist, curnode->data); */
+/*       curnode = g_slist_next(curnode); */
+/*     } */
+
+/*     if(g_slist_length(subiti.oplist) > 1) { */
+/*       if(curchar) */
+/*     cbe_skel_interface_print_relayers(&subiti); */
+/*       else */
+/*     g_error("two ops with same name!!!!"); */
+/*     } else { */
+/*       if(strlen(opi->opname + iti->curlevel)) */
+/*     fprintf(iti->ci->fh, "if(strcmp((opname + %d), \"%s\")) break;\n", */
+/*             iti->curlevel + 1, opi->opname + iti->curlevel+1); */
+/*       fprintf(iti->ci->fh, "*impl = (gpointer)servant->vepv->%s_epv->%s;\n", */
+/*           opi->iface_id, opi->opname); */
+/*       fprintf(iti->ci->fh, "{Forb_IInterface *volatile _t_=&%s__iinterface;*m_data = (gpointer)&_t_->methods._buffer [%d];}\n", */
+/*           opi->iface_id, opi->idx); */
+/*       fprintf(iti->ci->fh, "return (ForbSmallSkeleton)_FORB_skel_small_%s_%s;\n", */
+/*           opi->iface_id, opi->opname); */
+/*     } */
+/*     fprintf(iti->ci->fh, "break;\n"); */
+/*     g_slist_free(subiti.oplist); */
+/*   } */
+/*   fprintf(iti->ci->fh, "default: break; \n}\n"); */
+/* } */
+
+/* static void */
+/* cbe_skel_interface_print_relayer(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci) */
+/* { */
+/*   char *id; */
+/*   CBESkelInterfaceTraverseInfo iti; */
+
+/*   id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0); */
+/*   fprintf(ci->fh, "static ForbSmallSkeleton get_skel_small_%s(POA_%s *servant,\nconst char *opname," */
+/*       "gpointer *m_data, gpointer *impl)\n{\n", id, id); */
+
+/*   iti.ci = ci; */
+/*   iti.oplist = NULL; */
+/*   iti.curlevel = 0; */
+
+/*   IDL_tree_traverse_parents(tree, */
+/*                         (GFunc)cbe_skel_interface_add_relayer, &iti); */
+
+/*   cbe_skel_interface_print_relayers(&iti); */
+
+/*   g_slist_foreach(iti.oplist, (GFunc)cbe_skel_free_op_info, NULL); */
+/*   g_slist_free(iti.oplist); */
+
+/*   fprintf(ci->fh, "return NULL;\n"); */
+/*   fprintf(ci->fh, "}\n\n"); */
+
+/*   g_free(id); */
+/* } */
+
+typedef struct {
+       OIDL_C_Info *ci;
+       const char  *for_id;
+} CBESkelVEPVMapTraverseInfo;
+
+/* static void */
+/* cbe_skel_interface_print_vepvmap_offsets (IDL_tree node, CBESkelVEPVMapTraverseInfo *ti) */
+/* { */
+/*     char *id; */
+/*     id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_INTERFACE (node).ident), "_", 0); */
+/*     fprintf (ti->ci->fh, "(CORBA_unsigned_long) %s__classid,\n", id); */
+/*     fprintf (ti->ci->fh, "FORB_VEPV_OFFSET (POA_%s__vepv, %s_epv),\n", ti->for_id, id); */
+/*     g_free (id); */
+/* } */
+
+/**
+ * If the type specified in @a type_spec is dynamically allocated
+ * (such as string, sequence or object reference), the parameters of
+ * this type must be freed after they are not needed. For input
+ * parameter this is after the implementation is called, for out and
+ * inout return parameters after the returned value is serialized.
+ */
+static void free_memory_if_needed(IDL_tree type_spec, const char *name, int n, OIDL_C_Info *ci)
+{
+  type_spec = forb_cbe_get_typespec(type_spec);
+  /* forb_idl_print_node(type_spec, 7); */
+  switch(IDL_NODE_TYPE(type_spec)) {
+  case IDLN_TYPE_STRING:
+  case IDLN_TYPE_WIDE_STRING:
+    fprintf(ci->fh, "    ");
+    fprintf(ci->fh, "forb_free(%s);\n", name);
+    break;
+  case IDLN_TYPE_ARRAY:
+    break;
+  case IDLN_TYPE_SEQUENCE: {
+    char *dot = n==2?"->":".";
+    IDL_tree simple_type = forb_cbe_get_typespec(IDL_TYPE_SEQUENCE(type_spec).simple_type_spec);
+
+    fprintf(ci->fh, "    if (CORBA_sequence_get_release(%s%s)) {\n",
+           n==2?"":"&",name);
+    if (IDLN_NATIVE == IDL_NODE_TYPE(simple_type)) {
+      fprintf(ci->fh, "      int i;\n"
+                     "      for (i=0; i<%s%s_length; i++)\n"
+                     "          %s_free(%s%s_buffer[i]);\n",
+             name, dot, forb_cbe_get_typespec_str(IDL_NATIVE(type_spec).ident),
+             name, dot);
+    }
+    fprintf(ci->fh, "      forb_free(%s%s_buffer);\n"
+                   "    }\n", name, dot);
+    if (n==2) {
+           fprintf(ci->fh, "    ");
+           fprintf(ci->fh, "forb_free(%s);\n", name);
+    }
+    break;
+  }
+  case IDLN_NATIVE:
+    fprintf(ci->fh, "    ");
+    fprintf(ci->fh, "%s_free(%s);\n",
+           forb_cbe_get_typespec_str(IDL_NATIVE(type_spec).ident),
+           name);
+    return;
+  case IDLN_INTERFACE:
+    fprintf(ci->fh, "    ");
+    fprintf(ci->fh, "forb_object_release(%s);\n", name);
+    break;
+  default:
+    break;
+  }
+
+}
+
+static void ck_output_op_skel(IDL_tree op, char *intf_id, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+       char *id, *id_plain;
+       IDL_tree sub;
+       gboolean  has_retval, has_args;
+       const char *const seq_init = " = {0,0,NULL}";
+
+       has_retval = IDL_OP_DCL (op).op_type_spec != NULL;
+       has_args   = IDL_OP_DCL (op).parameter_dcls != NULL;
+       
+       id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(op).ident), "_", 0);
+       id_plain = IDL_IDENT(IDL_OP_DCL(op).ident).str;
+       fprintf(ci->fh, "static void\n"
+               "forb_skel_%s(FORB_CDR_Codec *cin, FORB_CDR_Codec *cout, %s _obj, struct forb_env *env)\n"
+               "{\n",
+               id, intf_id);
+/*     fprintf(ci->fh, "  if (_obj->interface != %s_interface) {\n", intf_id); */
+/*     fprintf(ci->fh, "    env->major = FORB_EX_BAD_OPERATION;\n" */
+/*                     "    return;\n" */
+/*                     "  }\n"); */
+       fprintf(ci->fh, "  if (_%s_impl(_obj) && _%s_impl(_obj)->%s) {\n", intf_id, intf_id, id_plain);
+
+       /* Declare variables for parameters */
+       for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+               IDL_tree        parm = IDL_LIST (sub).data;
+               IDL_ParamRole   role;
+               IDL_tree        ts = forb_cbe_get_typespec(parm);
+               gboolean        isSlice;
+               int             n;
+               char            *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+               role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+               n = oidl_param_info (ts, role, &isSlice);
+
+               fprintf(ci->fh, "    ");
+               forb_cbe_write_typespec(ci->fh, IDL_PARAM_DCL(parm).param_type_spec);
+               fprintf(ci->fh, " %s%s%s;\n",
+                       n == 2 ? "*":"",
+                       name,
+                       (n < 2 && IDL_NODE_TYPE(ts) == IDLN_TYPE_SEQUENCE)?seq_init : "");
+       }
+       if (has_retval) {
+               fprintf (ci->fh, "    ");
+               forb_cbe_write_param_typespec (ci->fh, op);
+               fprintf (ci->fh, " _forb_ret;\n"); /* TODO: seq_init */
+       }
+
+       /* Deserialize in parameters */
+       for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+               IDL_tree        parm = IDL_LIST (sub).data;
+               IDL_ParamRole   role;
+               role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+               if (role == DATA_IN || role == DATA_INOUT) {
+                       char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+                       fprintf(ci->fh, "    if (!");
+                       forb_cbe_write_typespec(ci->fh, IDL_PARAM_DCL(parm).param_type_spec);
+                       fprintf(ci->fh, "_deserialize(cin, &%s)) {\n", name);
+                       fprintf(ci->fh, "      env->major = FORB_EX_MARSHAL; goto exception;\n    }\n");
+               }
+       }
+
+       /* Call the implementation */
+       fprintf(ci->fh, "    ");
+       if (has_retval)
+               fprintf(ci->fh, "_forb_ret = ");
+       fprintf(ci->fh, "_%s_impl(_obj)->%s(_obj, ",
+               intf_id, id_plain);
+       for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+               IDL_tree        parm = IDL_LIST (sub).data;
+               IDL_ParamRole   role;
+               IDL_tree        ts = forb_cbe_get_typespec(parm);
+               gboolean        isSlice;
+               int             n;
+               char            *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+               role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+               n = oidl_param_info (ts, role, &isSlice);
+
+               fprintf(ci->fh, "%s%s, ", n?"&":"", name);
+       }
+       fprintf(ci->fh, "env);\n");
+       fprintf(ci->fh,
+               "    if (forb_exception_occurred(env)) goto exception;\n");
+       if (has_retval) {
+         fprintf(ci->fh, "    ");
+         forb_cbe_write_typespec(ci->fh, IDL_OP_DCL(op).op_type_spec);
+         fprintf(ci->fh, "_serialize(cout, &_forb_ret);\n");
+       }
+       for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+               IDL_tree        parm = IDL_LIST (sub).data;
+               IDL_ParamRole   role;
+               IDL_tree        ts = forb_cbe_get_typespec(parm);
+               gboolean        isSlice;
+               int             n;
+               char            *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+               role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+               n = oidl_param_info (ts, role, &isSlice);
+               if (role == DATA_OUT || role == DATA_INOUT) {
+                 fprintf(ci->fh, "    ");
+                 forb_cbe_write_typespec(ci->fh, IDL_PARAM_DCL(parm).param_type_spec);
+                 fprintf(ci->fh, "_serialize(cout, %s%s);\n", n==2?"":"&", name);
+               }
+       }
+       fprintf(ci->fh, "exception:;\n");
+
+       /* Free all dynamically allocated parameteres and retvals */
+       if (has_retval) {
+               free_memory_if_needed(IDL_OP_DCL(op).op_type_spec, "_forb_ret", 0, ci);
+       }
+       for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+               IDL_tree        parm = IDL_LIST (sub).data;
+               char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+               IDL_ParamRole   role;
+               IDL_tree        ts = forb_cbe_get_typespec(parm);
+               gboolean        isSlice;
+               int             n;
+               role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+               n = oidl_param_info (ts, role, &isSlice);
+               free_memory_if_needed(IDL_PARAM_DCL(parm).param_type_spec, name, n, ci);
+       }
+
+       fprintf(ci->fh, "  } else {\n");
+       fprintf(ci->fh, "    env->major = FORB_EX_NO_IMPLEMENT;\n");
+       fprintf(ci->fh, "  }\n");
+       fprintf(ci->fh, "}\n\n");
+       g_free(id);
+}
+
+static void
+cbe_skel_do_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+  char *id;
+  IDL_tree pnt;
+  IDL_tree sub;
+  //int i;
+  //CBESkelVEPVMapTraverseInfo ti;
+  int num_methods = 0;
+
+  /* PIDL methods dont have normal skel functions. */
+  for ( pnt=tree; pnt; pnt=IDL_NODE_UP(pnt) ) {
+      if ( pnt->declspec & IDLF_DECLSPEC_PIDL )
+       return;
+  }
+
+  id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0);
+
+  fprintf(ci->fh, "#define _%s_impl(obj) ((struct forb_%s_impl*)(obj)->implementation)\n\n", id, id);
+  fprintf(ci->fh, "static const struct forb_interface %s_interface;\n\n", id);
+  
+  for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) {
+    IDL_tree cur = IDL_LIST(sub).data;
+    
+    switch(IDL_NODE_TYPE(cur)) {
+    case IDLN_OP_DCL:
+      ck_output_op_skel(cur, id, rinfo, ci);
+      num_methods++;
+      break;
+    default:
+      break;
+    }
+  }
+
+  fprintf(ci->fh, "static const forb_skel_func %s_skeletons[%d] = {\n",
+         id, num_methods);
+  for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) {
+    IDL_tree cur = IDL_LIST(sub).data;
+    
+    switch(IDL_NODE_TYPE(cur)) {
+    case IDLN_OP_DCL: {
+      char *op_id;
+      op_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(cur).ident), "_", 0);
+      fprintf(ci->fh, "  forb_skel_%s,\n", op_id);
+      g_free(op_id);
+      break;
+    }
+    default:
+      break;
+    }
+  }
+  fprintf(ci->fh, "};\n\n");
+
+  fprintf(ci->fh, "static const struct forb_interface %s_interface = {\n", id);
+  fprintf(ci->fh, "  .name = \"%s\",\n", id);
+  fprintf(ci->fh, "  .num_methods = %d,\n", num_methods);
+  fprintf(ci->fh, "  .skeletons = %s_skeletons,\n", id);
+  fprintf(ci->fh, "  .type_hash = 0 /* not implemented */\n");
+  fprintf(ci->fh, "};\n\n");
+
+/*   fprintf(ci->fh, "void forb_register_%s_interface(void)\n" */
+/*               "{\n" */
+/*               "  forb_register_interface(&%s_interface);\n" */
+/*               "}\n\n", id, id); */
+
+  fprintf(ci->fh, "%s forb_%s_new(forb_orb orb, const struct forb_%s_impl *impl,"
+                 "void *instance_data)\n"
+                 "{\n"
+                 "  %s obj = forb_object_new(orb, NULL, 0);\n"
+                 "  if (obj) {\n"
+                 "    obj->instance_data = instance_data;\n"
+                 "    obj->implementation = impl;\n"
+                 "    obj->interface = &%s_interface;\n"
+                 "  }\n"
+                 "  return obj;\n"
+         "}\n\n", id, id, id, id, id);
+  fprintf(ci->fh, "\n");
+  
+
+/*   cbe_skel_interface_print_relayer(tree, rinfo, ci); */
+
+/*   fprintf(ci->fh, */
+/*       "void POA_%s__init(PortableServer_Servant servant,\nCORBA_Environment *env)\n", */
+/*       id); */
+/*   fprintf(ci->fh, "{\n"); */
+/*   fprintf(ci->fh,"  static PortableServer_ClassInfo class_info = {"); */
+
+/*   fprintf(ci->fh, "NULL, (Forb_small_impl_finder)&get_skel_small_%s, ", id); */
+
+/*   fprintf(ci->fh,"\"%s\", &%s__classid, NULL, &%s__iinterface};\n", */
+/*       IDL_IDENT(IDL_INTERFACE(tree).ident).repo_id, id, id); */
+
+/*   fprintf(ci->fh,"  PortableServer_ServantBase__init (" */
+/*              "       ((PortableServer_ServantBase *)servant), env);\n"); */
+
+/*   for(curitem = IDL_INTERFACE(tree).inheritance_spec; curitem; */
+/*       curitem = IDL_LIST(curitem).next) { */
+/*     id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_LIST(curitem).data), */
+/*                               "_", 0); */
+/*     fprintf(ci->fh, "  POA_%s__init(servant, env);\n", id2); */
+/*     g_free(id2); */
+/*   } */
+
+  /* registering after other __inits() makes the classids increment nicely. */
+/*   fprintf (ci->fh, "   Forb_skel_class_register (&class_info,\n"); */
+/*   fprintf (ci->fh, "   (PortableServer_ServantBase *)servant, POA_%s__fini,\n", id); */
+/*   fprintf (ci->fh, "   FORB_VEPV_OFFSET (POA_%s__vepv, %s_epv),\n", id, id); */
+/*   ti.for_id = id; ti.ci = ci; */
+/*   IDL_tree_traverse_parents_full (tree, (GFunc) cbe_skel_interface_print_vepvmap_offsets, &ti, FALSE); */
+/*   fprintf (ci->fh, "   (CORBA_unsigned_long) 0);"); */
+
+/*   fprintf(ci->fh, "}\n\n"); */
+
+/*   fprintf(ci->fh, */
+/*       "void POA_%s__fini(PortableServer_Servant servant,\nCORBA_Environment *env)\n", */
+/*       id); */
+/*   fprintf(ci->fh, "{\n"); */
+/*   if(IDL_INTERFACE(tree).inheritance_spec) */
+/*     { */
+/*       for(i = IDL_list_length(IDL_INTERFACE(tree).inheritance_spec) - 1; */
+/*       i >= 0; i--) { */
+/*     curitem = IDL_list_nth(IDL_INTERFACE(tree).inheritance_spec, i); */
+/*     id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_LIST(curitem).data), */
+/*                                   "_", 0); */
+/*     /\* XXX fixme - this is going to call ServantBase__fini multiple times *\/ */
+/*     fprintf(ci->fh, "  POA_%s__fini(servant, env);\n", */
+/*             id2); */
+/*     g_free(id2); */
+/*       } */
+/*     } */
+/*   fprintf(ci->fh, "  PortableServer_ServantBase__fini(servant, env);\n"); */
+/*   fprintf(ci->fh, "}\n\n"); */
+
+  g_free(id);
+}
+
+void
+forb_idl_output_c_skeletons (IDL_tree       tree,
+                             OIDL_Run_Info *rinfo,
+                             OIDL_C_Info   *ci)
+{
+       fprintf (ci->fh, OIDL_C_WARNING);
+/*     fprintf (ci->fh, "#include <string.h>\n"); */
+/*     fprintf (ci->fh, "#define FORB2_STUBS_API\n"); */
+       fprintf (ci->fh, "#include \"%s.h\"\n\n", ci->base_name);
+       fprintf(ci->fh, "#include <forb/cdr.h>\n");
+       fprintf(ci->fh, "#include <forb/forb-internal.h>\n");
+       fprintf(ci->fh, "#include <forb/object.h>\n\n");
+
+       ck_output_poastuff (tree, rinfo, ci);
+}
diff --git a/src/forb/forb-idl/forb-idl-c-stubs.c b/src/forb/forb-idl/forb-idl-c-stubs.c
new file mode 100644 (file)
index 0000000..f553283
--- /dev/null
@@ -0,0 +1,208 @@
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+
+static void
+cs_output_stub (IDL_tree     tree,
+               OIDL_C_Info *ci,
+               int         *idx)
+{
+       FILE     *of = ci->fh;
+       IDL_tree  sub;
+       char     *iface_id;
+       char     *opname;
+       char     *opname_plain;
+       gboolean  has_retval, has_args;
+
+       g_return_if_fail (idx != NULL);
+
+       iface_id = IDL_ns_ident_to_qstring (
+                       IDL_IDENT_TO_NS (IDL_INTERFACE (
+                               IDL_get_parent_node (tree, IDLN_INTERFACE, NULL)
+                                       ).ident), "_", 0);
+       opname_plain = IDL_IDENT(IDL_OP_DCL (tree).ident).str;
+       opname = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_OP_DCL (tree).ident), "_", 0);
+
+       has_retval = IDL_OP_DCL (tree).op_type_spec != NULL;
+       has_args   = IDL_OP_DCL (tree).parameter_dcls != NULL;
+
+       forb_cbe_op_write_proto (of, tree, "", FALSE);
+
+       fprintf (of, "\n{\n");
+
+       if (has_retval) {
+               fprintf (of, "  ");
+               forb_cbe_write_param_typespec (of, tree);
+               fprintf (of, " " FORB_RETVAL_VAR_NAME ";\n");
+       }
+
+/*     fprintf(of, "  if (_obj->type != %s_type) {\n" */
+/*                 "    ev->major = FORB_EX_BAD_OPERATION;\n", iface_id); */
+/*     if (has_retval) { */
+/*             fprintf(of, "    return "FORB_RETVAL_VAR_NAME";\n"); */
+/*     } */
+        fprintf(of, "  if (ev) ev->major = FORB_EX_NONE;\n");
+        fprintf(of, "  if (forb_object_is_local(_obj)) {\n");
+        fprintf(of, "    if (!_obj->interface ||\n"
+                    "        strncmp(_obj->interface->name, \"%s\", %zd) != 0) {\n"
+                    "      ev->major = FORB_EX_BAD_OPERATION;\n"
+                    "      return %s;\n"
+                    "    }\n", iface_id, strlen(iface_id), has_retval ? FORB_RETVAL_VAR_NAME : "");
+       fprintf(of, "    ");
+       if (has_retval) {
+               fprintf(of, FORB_RETVAL_VAR_NAME " = ");
+       }
+       fprintf(of, "_%s_impl(_obj)->%s(_obj, ",
+               iface_id, opname_plain);
+       for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+               IDL_tree parm = IDL_LIST (sub).data;
+               fprintf (of, "%s, ", IDL_IDENT (IDL_PARAM_DCL (parm).simple_declarator).str);
+       }
+       fprintf(of, "ev);\n");
+       
+       fprintf(of, "  } else {\n");
+       fprintf(of, "    /* remote object */\n"
+                   "    forb_request_t req;\n");
+       fprintf(of, "    ex_on_fail(forb_request_init(&req, _obj) == 0, FORB_EX_INTERNAL);\n");
+       fprintf(of, "    forb_iop_prepare_request(&req, \"%s\", FORB_METHOD_INDEX(%s), ev);\n",
+               iface_id, opname);
+       fprintf(of, "    if (forb_exception_occurred(ev)) goto exception;\n");
+       for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+               IDL_tree        parm = IDL_LIST (sub).data;
+               IDL_ParamRole   role;
+               role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+               if (role == DATA_IN || role == DATA_INOUT) {
+                 char      *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+                 gboolean  isSlice;
+                 IDL_tree  ts = forb_cbe_get_typespec(parm);
+                 int       n = oidl_param_info (ts, role, &isSlice);
+                 fprintf(of, "    ex_on_fail(");
+                 forb_cbe_write_typespec(of, IDL_PARAM_DCL(parm).param_type_spec);
+                 fprintf(of, "_serialize(&req.cdr_request, %s%s), FORB_EX_IMP_LIMIT);\n",
+                         n == 0 ? "&":"", name);
+               }
+       }
+       fprintf(of, "    forb_request_send(&req, ev);\n");
+       fprintf(of, "    if (forb_exception_occurred(ev)) goto exception;\n");
+       fprintf(of, "    forb_request_wait_for_reply(&req);\n");
+       fprintf(of, "    if (forb_exception_occurred(ev)) goto exception;\n");
+       if (has_retval) {
+         fprintf(of, "    ");
+         forb_cbe_write_typespec(of, IDL_OP_DCL(tree).op_type_spec);
+         fprintf(of, "_deserialize(req.cdr_reply, &"FORB_RETVAL_VAR_NAME");\n");
+       }
+       for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+               IDL_tree        parm = IDL_LIST (sub).data;
+               IDL_ParamRole   role;
+               role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+               if (role == DATA_OUT || role == DATA_INOUT) {
+                 char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+                 gboolean  isSlice;
+                 IDL_tree  ts = forb_cbe_get_typespec(parm);
+                 int       n = oidl_param_info (ts, role, &isSlice);
+                 if (IDL_NODE_TYPE(forb_cbe_get_typespec(parm)) == IDLN_TYPE_SEQUENCE &&
+                     role == DATA_OUT) { /* Allocate out sequence */
+                         fprintf(ci->fh, "    *%s = forb_malloc(sizeof(**%s));\n", name, name);
+                         fprintf(ci->fh, "    if (!*%s) { ev->major = FORB_EX_NO_MEMORY; goto exception; }\n", name);
+                         fprintf(ci->fh, "    memset(*%s, 0, sizeof(**%s));\n", name, name);
+                         fprintf(ci->fh, "    CORBA_sequence_set_release(*%s, CORBA_TRUE);\n", name);
+                         /* TODO: Free previously allocated parameters on no memory error. */
+                 }
+                 fprintf(of, "    ");
+                 forb_cbe_write_typespec(of, IDL_PARAM_DCL(parm).param_type_spec);
+                 fprintf(ci->fh, "_deserialize(req.cdr_reply, %s%s);\n", n==2?"*":"", name);
+               }
+       }
+       fprintf(of, "    forb_request_signal_processed(&req);\n"
+                   "exception:\n"
+                   "    forb_request_destroy(&req);\n");
+       fprintf(of, "  }\n");
+       if (has_retval) {
+               fprintf(of, "  return " FORB_RETVAL_VAR_NAME ";\n");
+       }
+
+       fprintf (of, "}\n\n");
+
+       g_free (iface_id);
+       g_free (opname);
+
+       (*idx)++;
+}
+
+static void
+cs_output_stubs (IDL_tree     tree,
+                OIDL_C_Info *ci,
+                int         *idx)
+{
+       if (!tree)
+               return;
+
+       switch (IDL_NODE_TYPE (tree)) {
+       case IDLN_MODULE:
+               cs_output_stubs (IDL_MODULE (tree).definition_list, ci, idx);
+               break;
+       case IDLN_LIST: {
+               IDL_tree sub;
+
+               for (sub = tree; sub; sub = IDL_LIST (sub).next)
+                       cs_output_stubs (IDL_LIST (sub).data, ci, idx);
+               break;
+               }
+       case IDLN_ATTR_DCL: {
+/*             IDL_tree node; */
+      
+/*             for (node = IDL_ATTR_DCL (tree).simple_declarations; node; node = IDL_LIST (node).next) { */
+/*                     OIDL_Attr_Info *ai; */
+
+/*                     ai = IDL_LIST (node).data->data; */
+       
+/*                     cs_output_stubs (ai->op1, ci, idx); */
+
+/*                     if (ai->op2) */
+/*                             cs_output_stubs (ai->op2, ci, idx); */
+/*             } */
+               break;
+               }
+       case IDLN_INTERFACE: {
+               int real_idx = 0;
+               char *id;
+               /* Do not output skeletons for PIDL interfaces */
+               if ((tree->declspec & IDLF_DECLSPEC_PIDL) == 0) {
+                 id = IDL_ns_ident_to_qstring (IDL_INTERFACE (tree).ident, "_", 0);
+                 fprintf(ci->fh, "#define _%s_impl(obj) ((struct forb_%s_impl*)(obj)->implementation)\n\n",
+                         id, id);
+                 g_free(id);
+                 cs_output_stubs (IDL_INTERFACE (tree).body, ci, &real_idx);
+               }
+               break;
+               }
+       case IDLN_OP_DCL:
+               cs_output_stub (tree, ci, idx);
+               break;
+       default:
+               break;
+       }
+}
+
+void
+forb_idl_output_c_stubs (IDL_tree       tree,
+                         OIDL_Run_Info *rinfo,
+                         OIDL_C_Info   *ci)
+{
+       fprintf (ci->fh, OIDL_C_WARNING);
+       fprintf (ci->fh, "#include <string.h>\n");
+/*     fprintf (ci->fh, "#define FORB2_STUBS_API\n"); */
+       fprintf (ci->fh, "#include <forb/forb-internal.h>\n");
+       fprintf (ci->fh, "#include <forb/request.h>\n");
+       fprintf (ci->fh, "#include <forb/iop.h>\n");
+       fprintf (ci->fh, "#include <forb/cdr.h>\n");
+       fprintf (ci->fh, "#include <forb/object.h>\n\n");
+       fprintf (ci->fh, "#include \"%s.h\"\n\n", ci->base_name);
+
+       fprintf (ci->fh, "#define ex_on_fail(command, ex) if (!(command)) do { ev->major = (ex); goto exception; } while(0)\n");
+       fprintf (ci->fh, "#define FORB_REQEST_HDR_SIZE (forb_iop_MESSAGE_HEADER_SIZE + forb_iop_REQUEST_HEADER_SIZE)\n\n");
+
+       cs_output_stubs (tree, ci, NULL);
+}
diff --git a/src/forb/forb-idl/forb-idl-c-typecode.c b/src/forb/forb-idl/forb-idl-c-typecode.c
new file mode 100644 (file)
index 0000000..c0023fb
--- /dev/null
@@ -0,0 +1,1039 @@
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+#include <inttypes.h>
+
+typedef struct {
+       IDL_tree     ts;
+       char        *structname;
+       char        *substructname;
+       int          array_gen_ctr;
+} CBETCGenInfo;
+
+static int random_id = 0;
+
+static char *forb_generate_tcstruct_name (IDL_tree     ts);
+static void  cbe_tc_generate              (OIDL_C_Info *ci, CBETCGenInfo *tci);
+
+void
+forb_output_typecode (OIDL_C_Info *ci,
+                      IDL_tree     node)
+{
+       CBETCGenInfo tci;
+
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_DCL:
+       case IDLN_TYPE_STRUCT:
+       case IDLN_TYPE_UNION:
+       case IDLN_TYPE_ENUM:
+       case IDLN_EXCEPT_DCL:
+       case IDLN_TYPE_SEQUENCE:
+       case IDLN_INTERFACE:
+               break;
+       default:
+               g_error ("You can't produce a typecode for a %s", 
+                        IDL_tree_type_names[IDL_NODE_TYPE (node)]);
+       }
+
+       tci.ts            = node;
+       tci.structname    = forb_generate_tcstruct_name (node);
+       tci.substructname = NULL;
+       tci.array_gen_ctr = 0;
+
+       cbe_tc_generate (ci, &tci);
+
+       g_free (tci.structname);
+}
+
+static char *
+forb_generate_tcstruct_name (IDL_tree node)
+{
+       GString *tmpstr;
+       char    *retval;
+
+       tmpstr = g_string_new (NULL);
+
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_INTEGER:
+       case IDLN_TYPE_ANY:
+       case IDLN_TYPE_STRING:
+       case IDLN_TYPE_WIDE_STRING:
+       case IDLN_TYPE_CHAR:
+       case IDLN_TYPE_WIDE_CHAR:
+       case IDLN_TYPE_FLOAT:
+       case IDLN_TYPE_BOOLEAN:
+       case IDLN_TYPE_OCTET:
+       case IDLN_TYPE_SEQUENCE:
+       case IDLN_TYPE_STRUCT:
+       case IDLN_TYPE_UNION:
+       case IDLN_TYPE_ENUM:
+       case IDLN_IDENT:
+       case IDLN_EXCEPT_DCL:
+       case IDLN_INTERFACE:
+       case IDLN_FORWARD_DCL:
+       case IDLN_TYPE_OBJECT: {
+               char *typespec = forb_cbe_get_typespec_str (node);
+
+               g_string_printf (tmpstr, "TC_%s", typespec);
+
+               g_free (typespec);
+               }
+               break;
+       default:
+               g_string_printf (tmpstr, "anonTC_%d", random_id++);
+               break;
+       }
+
+       retval = tmpstr->str;
+       g_string_free (tmpstr, FALSE);
+
+       return retval;
+}
+
+static void
+forb_output_tcstruct_anon_subnames_array (FILE *fh, IDL_tree node, int subnames_id)
+{
+       IDL_tree l;
+
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_ENUM:
+               if (!IDL_TYPE_ENUM (node).enumerator_list)
+                       break;
+
+               fprintf (fh, "static const char *anon_subnames_array%d[] = {", subnames_id);
+
+               for (l = IDL_TYPE_ENUM (node).enumerator_list; l; l = IDL_LIST (l).next) {
+                       g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_IDENT);
+
+                       fprintf (fh, "\"%s\"", IDL_IDENT (IDL_LIST (l).data).str );
+                       if (IDL_LIST (l).next)
+                               fprintf (fh, ", ");
+               }
+
+               fprintf (fh, "};\n");
+               break;
+       case IDLN_EXCEPT_DCL:
+       case IDLN_TYPE_STRUCT:
+               if (!IDL_TYPE_STRUCT (node).member_list)
+                       break;
+
+               fprintf (fh, "static const char *anon_subnames_array%d[] = {", subnames_id);
+
+               for (l = IDL_TYPE_STRUCT (node).member_list; l; l = IDL_LIST (l).next) {
+                       IDL_tree dcl;
+
+                       g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_MEMBER);
+
+                       for (dcl = IDL_MEMBER (IDL_LIST (l).data).dcls; dcl;
+                            dcl = IDL_LIST (dcl).next) {
+                               IDL_tree p = IDL_LIST (dcl).data;
+
+                               g_assert (IDL_NODE_TYPE (p) == IDLN_IDENT ||
+                                         IDL_NODE_TYPE (p) == IDLN_TYPE_ARRAY);
+
+                               if (IDL_NODE_TYPE (p) == IDLN_IDENT)
+                                       fprintf (fh, "\"%s\"", IDL_IDENT (p).str);
+
+                               else /* IDLN_TYPE_ARRAY */
+                                       fprintf (fh, "\"%s\"", 
+                                                IDL_IDENT (IDL_TYPE_ARRAY (p).ident).str);
+       
+                               if (IDL_LIST (dcl).next || IDL_LIST (l).next)
+                                       fprintf (fh, ", ");
+                       }
+               }
+
+               fprintf (fh, "};\n");
+               break;
+       case IDLN_TYPE_UNION:
+               if (!IDL_TYPE_UNION (node).switch_body)
+                       break;
+
+               fprintf (fh, "static const char * anon_subnames_array%d[] = {", subnames_id);
+
+               for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next) {
+                       IDL_tree dcl, label;
+                       const char *subname;
+
+                       g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_CASE_STMT);
+
+                       dcl = IDL_LIST (IDL_MEMBER (
+                               IDL_CASE_STMT (IDL_LIST (l).data).element_spec).dcls).data;
+
+                       g_assert (IDL_NODE_TYPE (dcl) == IDLN_IDENT ||
+                                 IDL_NODE_TYPE (dcl) == IDLN_TYPE_ARRAY);
+
+                       if (IDL_NODE_TYPE (dcl) == IDLN_IDENT)
+                               subname = IDL_IDENT (dcl).str;
+                       else /* IDLN_TYPE_ARRAY */
+                               subname = IDL_IDENT (IDL_TYPE_ARRAY (dcl).ident).str;
+
+                       /* output the name once for each label */
+                       for (label = IDL_CASE_STMT (IDL_LIST (l).data).labels;
+                            label != NULL; label = IDL_LIST (label).next) {
+                               fprintf (fh, "\"%s\"", subname);
+                               if (IDL_LIST (label).next)
+                                       fprintf (fh, ", ");
+                       }
+
+                       if (IDL_LIST (l).next)
+                               fprintf (fh, ", ");
+               }
+               fprintf (fh, "};\n");
+               break;
+       default:
+               break;
+       }
+}
+
+static void
+forb_output_tcstruct_anon_subtypes_array (FILE     *fh,
+                                          IDL_tree  node,
+                                          int       subtypes_id,
+                                          char     *substructname)
+{
+       IDL_tree l;
+
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_EXCEPT_DCL:
+       case IDLN_TYPE_STRUCT:
+               if (!IDL_TYPE_STRUCT (node).member_list)
+                       break;
+
+               fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = {",
+                        subtypes_id);
+
+               for (l = IDL_TYPE_STRUCT (node).member_list; l; l = IDL_LIST (l).next) {
+                       IDL_tree  dcl;
+                       char     *tmpstr;
+
+                       dcl = IDL_MEMBER (IDL_LIST (l).data).type_spec;
+
+                       switch (IDL_NODE_TYPE (dcl)) {
+                       case IDLN_IDENT:
+                       case IDLN_INTERFACE:
+                       case IDLN_TYPE_OBJECT:
+                       case IDLN_FORWARD_DCL:
+                               dcl = forb_cbe_get_typespec (dcl);
+
+                               if (IDL_NODE_DECLSPEC (dcl) & IDLF_DECLSPEC_PIDL &&
+                                  (IDL_NODE_TYPE (dcl) == IDLN_INTERFACE ||
+                                   IDL_NODE_TYPE (dcl) == IDLN_FORWARD_DCL))
+                                       tmpstr = g_strdup ("Object");
+                               else
+                                       tmpstr = forb_cbe_get_typespec_str (
+                                                       IDL_MEMBER (IDL_LIST (l).data).type_spec);
+                               break;
+                       default:
+                               tmpstr = forb_cbe_get_typespec_str (
+                                               IDL_MEMBER (IDL_LIST (l).data).type_spec);
+                               break;
+                       }
+
+                       g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_MEMBER);
+
+                       for (dcl = IDL_MEMBER (IDL_LIST (l).data).dcls; dcl;
+                            dcl = IDL_LIST (dcl).next) {
+
+                               fprintf (fh, "(CORBA_TypeCode)&TC_%s_struct", tmpstr);
+
+                               if (IDL_LIST (dcl).next || IDL_LIST (l).next)
+                                       fprintf (fh, ", ");
+                       }
+
+                       g_free (tmpstr);
+               }
+
+               fprintf (fh, "};\n");
+
+               break;
+       case IDLN_TYPE_UNION:
+               if (!IDL_TYPE_UNION (node).switch_body)
+                       break;
+
+               fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = {", subtypes_id);
+
+               for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next) {
+                       IDL_tree  label, dcl;
+                       char     *tmpstr;
+
+                       g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_CASE_STMT);
+
+                       dcl = IDL_MEMBER (IDL_CASE_STMT (IDL_LIST (l).data).element_spec).type_spec;
+
+                       switch (IDL_NODE_TYPE (forb_cbe_get_typespec (dcl))) {
+                       case IDLN_INTERFACE:
+                       case IDLN_FORWARD_DCL:
+                               if (IDL_NODE_DECLSPEC (dcl) & IDLF_DECLSPEC_PIDL)
+                                       tmpstr = g_strdup ( "Object");
+                               else
+                                       tmpstr = forb_cbe_get_typespec_str (dcl);
+                               break;
+                       default:
+                               tmpstr = forb_cbe_get_typespec_str (dcl);
+                               break;
+                       }
+
+                       for (label = IDL_CASE_STMT (IDL_LIST (l).data).labels; label;
+                            label = IDL_LIST (label).next) {
+                               fprintf (fh, "(CORBA_TypeCode)&TC_%s_struct", tmpstr);
+
+                               if (IDL_LIST (label).next || IDL_LIST (l).next)
+                                       fprintf (fh, ", ");
+                       }
+
+                       g_free (tmpstr);
+               }
+
+               fprintf (fh, "};\n");
+
+               break;
+       case IDLN_TYPE_SEQUENCE: {
+               IDL_tree  seqts;
+               char     *tmpstr;
+
+               seqts = forb_cbe_get_typespec (IDL_TYPE_SEQUENCE (node).simple_type_spec);
+
+               fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = ", subtypes_id);
+
+               switch (IDL_NODE_TYPE (seqts)) {
+               case IDLN_INTERFACE:
+               case IDLN_FORWARD_DCL:
+                       if (IDL_NODE_DECLSPEC (seqts) && IDLF_DECLSPEC_PIDL)
+                               tmpstr = g_strdup ("Object");
+                       else
+                               tmpstr = forb_cbe_get_typespec_str (
+                                               IDL_TYPE_SEQUENCE (node).simple_type_spec);
+                       break;
+               default:
+                       tmpstr = forb_cbe_get_typespec_str (
+                                               IDL_TYPE_SEQUENCE (node).simple_type_spec);
+                       break;
+               }
+
+               fprintf (fh, "{(CORBA_TypeCode)&TC_%s_struct};\n", tmpstr);
+               g_free (tmpstr);
+
+               }
+               break;
+       case IDLN_TYPE_ARRAY:
+       case IDLN_IDENT:
+               fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = ", subtypes_id);
+               fprintf (fh, "{(CORBA_TypeCode)&%s_struct};\n", substructname);
+               break;
+       default:
+               break;
+       }
+}
+
+static int
+forb_output_tcstruct_anon_sublabels_array (FILE     *fh, 
+                                           IDL_tree  node,
+                                           int       sublabels_id)
+{
+       IDL_tree l, label;
+       int      index = 0;
+       int      default_index = -1;
+
+       if (IDL_NODE_TYPE (node) != IDLN_TYPE_UNION ||
+           !IDL_TYPE_UNION (node).switch_body)
+               return default_index;
+
+       fprintf (fh, "static FORB2_MAYBE_CONST CORBA_long anon_sublabels_array%d[] = {", sublabels_id);
+
+       for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next)
+               for (label = IDL_CASE_STMT (IDL_LIST (l).data).labels; label;
+                    label = IDL_LIST (label).next, index++) {
+
+                       if (IDL_LIST (label).data) {
+                               fprintf (fh, "(CORBA_long) ");
+
+                               forb_cbe_write_const (fh, IDL_LIST (label).data);
+
+                       } else { /* default case */
+                               fprintf (fh, "-1");
+                               default_index = index;
+                       }
+
+                       if (IDL_LIST (label).next || IDL_LIST (l).next)
+                               fprintf (fh, ", ");
+               }
+
+       fprintf (fh, "};\n");
+
+       return default_index;
+}
+
+static void
+forb_output_tcstruct_parent (FILE *fh)
+{
+       fprintf (fh, "{&Forb_TypeCode_epv, FORB_REFCOUNT_STATIC}");
+}
+
+static void
+forb_output_tcstruct_kind (FILE *fh, IDL_tree node, int array_gen_ctr)
+{
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_ARRAY:
+               if (array_gen_ctr)
+                       fprintf (fh, "CORBA_tk_array");
+               else
+                       fprintf (fh, "CORBA_tk_alias");
+               break;
+       case IDLN_IDENT:
+               fprintf (fh, "CORBA_tk_alias");
+               break;
+       case IDLN_TYPE_STRUCT:
+               fprintf (fh, "CORBA_tk_struct");
+               break;
+       case IDLN_TYPE_UNION:
+               fprintf (fh, "CORBA_tk_union");
+               break;
+       case IDLN_TYPE_ENUM:
+               fprintf (fh, "CORBA_tk_enum");
+               break;
+       case IDLN_TYPE_OBJECT:
+       case IDLN_INTERFACE:
+       case IDLN_FORWARD_DCL:
+               fprintf (fh, "CORBA_tk_objref");
+               break;
+       case IDLN_EXCEPT_DCL:
+               fprintf (fh, "CORBA_tk_except");
+               break;
+       case IDLN_TYPE_INTEGER:
+               fprintf (fh, "CORBA_tk_");
+
+               if (!IDL_TYPE_INTEGER (node).f_signed)
+                       fprintf (fh, "u");
+
+               switch (IDL_TYPE_INTEGER (node).f_type) {
+               case IDL_INTEGER_TYPE_SHORT:
+                       fprintf (fh, "short");
+                       break;
+               case IDL_INTEGER_TYPE_LONG:
+                       fprintf (fh, "long");
+                       break;
+               case IDL_INTEGER_TYPE_LONGLONG:
+                       fprintf (fh, "longlong");
+                       break;
+               }
+               break;
+       case IDLN_TYPE_FLOAT:
+               fprintf (fh, "CORBA_tk_");
+
+               switch (IDL_TYPE_FLOAT (node).f_type) {
+               case IDL_FLOAT_TYPE_FLOAT:
+                       fprintf (fh, "float");
+                       break;
+               case IDL_FLOAT_TYPE_DOUBLE:
+                       fprintf (fh, "double");
+                       break;
+               case IDL_FLOAT_TYPE_LONGDOUBLE:
+                       fprintf (fh, "longdouble");
+                       break;
+               }
+               break;
+       case IDLN_TYPE_BOOLEAN:
+               fprintf (fh, "CORBA_tk_boolean");
+               break;
+       case IDLN_TYPE_OCTET:
+               fprintf (fh, "CORBA_tk_octet");
+               break;
+       case IDLN_TYPE_STRING:
+               fprintf (fh, "CORBA_tk_string");
+               break;
+       case IDLN_TYPE_WIDE_STRING:
+               fprintf (fh, "CORBA_tk_wstring");
+               break;
+       case IDLN_TYPE_CHAR:
+               fprintf (fh, "CORBA_tk_char");
+               break;
+       case IDLN_TYPE_WIDE_CHAR:
+               fprintf (fh, "CORBA_tk_wchar");
+               break;
+       case IDLN_TYPE_ANY:
+               fprintf (fh, "CORBA_tk_any");
+               break;
+       case IDLN_TYPE_SEQUENCE:
+               fprintf (fh, "CORBA_tk_sequence");
+               break;
+       default:
+               g_message ("Type %s has no tk constant!",
+                          IDL_tree_type_names[IDL_NODE_TYPE (node)]);
+       }
+}
+
+static void
+forb_output_tcstruct_name (FILE *fh, IDL_tree node, int array_gen_ctr)
+{
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_STRUCT:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_STRUCT (node).ident).str);
+               break;
+       case IDLN_TYPE_UNION:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_UNION (node).ident).str);
+               break;
+       case IDLN_TYPE_ENUM:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_ENUM (node).ident).str);
+               break;
+       case IDLN_INTERFACE:
+       case IDLN_FORWARD_DCL:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_INTERFACE (node).ident).str);
+               break;
+       case IDLN_EXCEPT_DCL:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_EXCEPT_DCL (node).ident).str);
+               break;
+       case IDLN_IDENT:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (node).str);
+               break;
+       case IDLN_TYPE_ARRAY:
+               if (!array_gen_ctr)
+                       fprintf (fh, "(char *)\"%s\"", 
+                                IDL_IDENT (IDL_TYPE_ARRAY (node).ident).str);
+               else
+                       fprintf (fh, "NULL");
+               break;
+       default:
+               fprintf (fh, "NULL");
+               break;
+       }
+}
+
+static void
+forb_output_tcstruct_repo_id (FILE *fh, IDL_tree node, int array_gen_ctr)
+{
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_STRUCT:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_STRUCT (node).ident).repo_id);
+               break;
+       case IDLN_TYPE_UNION:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_UNION (node).ident).repo_id);
+               break;
+       case IDLN_TYPE_ENUM:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_ENUM (node).ident).repo_id);
+               break;
+       case IDLN_INTERFACE:
+       case IDLN_FORWARD_DCL:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_INTERFACE (node).ident).repo_id);
+               break;
+       case IDLN_EXCEPT_DCL:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_EXCEPT_DCL (node).ident).repo_id);
+               break;
+       case IDLN_IDENT:
+               fprintf (fh, "(char *)\"%s\"", IDL_IDENT (node).repo_id);
+               break;
+       case IDLN_TYPE_ARRAY:
+               if (!array_gen_ctr)
+                       fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_ARRAY (node).ident).repo_id);
+               else
+                       fprintf (fh, "NULL");
+               break;
+       default:
+               fprintf (fh, "NULL");
+               break;
+       }
+}
+
+static void
+forb_output_tcstruct_length (FILE *fh, IDL_tree node, int array_gen_ctr)
+{
+       int length = 0;
+
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_SEQUENCE:
+               if (IDL_TYPE_SEQUENCE (node).positive_int_const)
+                       length = IDL_INTEGER (IDL_TYPE_SEQUENCE (node).positive_int_const).value;
+               break;
+       case IDLN_TYPE_STRING:
+               if (IDL_TYPE_STRING (node).positive_int_const)
+                       length = IDL_INTEGER (IDL_TYPE_STRING (node).positive_int_const).value;
+               break;
+       case IDLN_TYPE_WIDE_STRING:
+               if (IDL_TYPE_WIDE_STRING (node).positive_int_const)
+                       length = IDL_INTEGER (IDL_TYPE_STRING (node).positive_int_const).value;
+               break;
+       case IDLN_TYPE_ARRAY:
+               if (array_gen_ctr) {
+                       IDL_tree sizer;
+
+                       sizer = IDL_list_nth (IDL_TYPE_ARRAY (node).size_list,
+                                             array_gen_ctr - 1);
+
+                       g_assert (IDL_NODE_TYPE (IDL_LIST (sizer).data) == IDLN_INTEGER);
+
+                       length = IDL_INTEGER (IDL_LIST (sizer).data).value;
+               }
+               break;
+       default:
+               length = 0;
+               break;
+       }
+
+       fprintf (fh, "%d", length);
+}
+
+static void
+forb_output_tcstruct_sub_parts (FILE *fh, IDL_tree node)
+{
+       int length = 0;
+
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_STRUCT:
+       case IDLN_EXCEPT_DCL: {
+               IDL_tree l;
+
+               for (l = IDL_TYPE_STRUCT (node).member_list; l; l = IDL_LIST (l).next) {
+                       IDL_tree member;
+
+                       member = IDL_LIST (l).data;
+
+                       g_assert (IDL_NODE_TYPE (member) == IDLN_MEMBER);
+
+                       length += IDL_list_length (IDL_MEMBER (member).dcls);
+               }
+               }
+               break;
+       case IDLN_TYPE_UNION: {
+               IDL_tree l;
+
+               for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next) {
+                       IDL_tree case_stmt;
+
+                       case_stmt = IDL_LIST (l).data;
+
+                       g_assert (IDL_NODE_TYPE (case_stmt) == IDLN_CASE_STMT);
+
+                       length += IDL_list_length (IDL_CASE_STMT (case_stmt).labels);
+               }
+               }
+               break;
+       case IDLN_TYPE_ENUM:
+               length = IDL_list_length (IDL_TYPE_ENUM (node).enumerator_list);
+               break;
+       case IDLN_IDENT:
+       case IDLN_TYPE_SEQUENCE:
+       case IDLN_TYPE_ARRAY:
+               length = 1;
+               break;
+       default:
+               length = 0;
+               break;
+       }
+
+       fprintf (fh, "%d\n", length);
+}
+
+static void
+forb_output_tcstruct_subnames (FILE *fh, IDL_tree node, int subnames_id)
+{
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_ENUM:
+               if (IDL_TYPE_ENUM (node).enumerator_list)
+                       fprintf (fh, "(char **)anon_subnames_array%d", subnames_id);
+               else
+                       fprintf (fh, "NULL");
+               break;
+       case IDLN_TYPE_UNION:
+               if (IDL_TYPE_UNION (node).switch_body)
+                       fprintf (fh, "(char **)anon_subnames_array%d", subnames_id);
+               else
+                       fprintf (fh, "NULL");
+               break;
+       case IDLN_TYPE_STRUCT:
+       case IDLN_EXCEPT_DCL:
+               if (IDL_TYPE_STRUCT (node).member_list)
+                       fprintf (fh, "(char **)anon_subnames_array%d", subnames_id);
+               else
+                       fprintf (fh, "NULL");
+               break;
+       default:
+               fprintf (fh, "NULL");
+               break;
+       }
+}
+
+static void
+forb_output_tcstruct_subtypes (FILE *fh, IDL_tree node, int subtypes_id)
+{
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_EXCEPT_DCL:
+       case IDLN_TYPE_STRUCT:
+               if (IDL_TYPE_STRUCT (node).member_list)
+                       fprintf (fh, "(CORBA_TypeCode *)anon_subtypes_array%d", subtypes_id);
+               else
+                       fprintf (fh, "NULL");
+               break;
+       case IDLN_TYPE_UNION:
+               if (IDL_TYPE_UNION (node).switch_body)
+                       fprintf (fh, "(CORBA_TypeCode *)anon_subtypes_array%d", subtypes_id);
+               else
+                       fprintf (fh, "NULL");
+               break;
+       case IDLN_TYPE_SEQUENCE:
+       case IDLN_TYPE_ARRAY:
+       case IDLN_IDENT:
+               fprintf (fh, "(CORBA_TypeCode *)anon_subtypes_array%d", subtypes_id);
+               break;
+       default:
+               fprintf (fh, "NULL");
+               break;
+       }
+}
+
+static void
+forb_output_tcstruct_sublabels (FILE *fh, IDL_tree node, int sublabels_id)
+{
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_UNION:
+               fprintf (fh, "(CORBA_long *)anon_sublabels_array%d", sublabels_id);
+               break;
+       default:
+               fprintf (fh, "NULL");
+               break;
+       }
+}
+
+static void
+forb_output_tcstruct_discriminator (FILE *fh, IDL_tree node)
+{
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_UNION: {
+               char *switch_type_spec_str;
+
+               switch_type_spec_str = 
+                       forb_cbe_get_typespec_str (IDL_TYPE_UNION (node).switch_type_spec);
+
+               fprintf (fh, "(CORBA_TypeCode)&TC_%s_struct", switch_type_spec_str);
+
+               g_free (switch_type_spec_str);
+               }
+               break;
+       default:
+               fprintf (fh, "CORBA_OBJECT_NIL");
+               break;
+       }
+}
+
+static void
+forb_output_tcstruct_recurse_depth (FILE *fh)
+{
+       fprintf (fh, "0");
+}
+
+static void
+forb_output_tcstruct_default_index (FILE *fh, int union_default_index)
+{
+       fprintf (fh, "%d", union_default_index);
+}
+
+static void
+forb_output_tcstruct_digits_scale (FILE *fh, IDL_tree node)
+{
+       if (IDL_NODE_TYPE (node) == IDLN_TYPE_FIXED) {
+               fprintf (fh, "%" PRId64 ", %" PRId64 ,
+                        IDL_INTEGER (IDL_TYPE_FIXED (node).positive_int_const).value,
+                        IDL_INTEGER (IDL_TYPE_FIXED (node).integer_lit).value);
+       }
+       else
+               fprintf (fh, "0, 0");
+}
+
+static void
+forb_add_align (GSList **max, const char *str)
+{
+       GSList *l;
+
+       for (l = *max; l; l = l->next) {
+               if (!strcmp (l->data, str))
+                       return;
+       }
+       *max = g_slist_prepend (*max, (gpointer) str);
+}
+
+static GSList *
+forb_find_c_align (GSList *max, IDL_tree node)
+{
+       node = forb_cbe_get_typespec (node);    
+
+       switch (IDL_NODE_TYPE (node)) {
+       case IDLN_TYPE_INTEGER:
+               switch (IDL_TYPE_INTEGER (node).f_type) {
+               case IDL_INTEGER_TYPE_SHORT:
+                       forb_add_align (&max, "FORB_ALIGNOF_CORBA_SHORT");
+                       break;
+               case IDL_INTEGER_TYPE_LONG:
+                       forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG");
+                       break;
+               case IDL_INTEGER_TYPE_LONGLONG:
+                       forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG_LONG");
+                       break;
+               }
+               break;
+       case IDLN_TYPE_FLOAT:
+               switch (IDL_TYPE_FLOAT (node).f_type) {
+               case IDL_FLOAT_TYPE_FLOAT:
+                       forb_add_align (&max, "FORB_ALIGNOF_CORBA_FLOAT");
+                       break;
+               case IDL_FLOAT_TYPE_DOUBLE:
+                       forb_add_align (&max, "FORB_ALIGNOF_CORBA_DOUBLE");
+                       break;
+               case IDL_FLOAT_TYPE_LONGDOUBLE:
+                       forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG_DOUBLE");
+                       break;
+               }
+               break;
+       case IDLN_TYPE_ENUM:
+               forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG");
+               break;
+       case IDLN_TYPE_CHAR: /* drop through */
+       case IDLN_TYPE_BOOLEAN:
+       case IDLN_TYPE_OCTET:
+               forb_add_align (&max, "FORB_ALIGNOF_CORBA_CHAR");
+               break;
+       case IDLN_TYPE_WIDE_CHAR:
+               forb_add_align (&max, "FORB_ALIGNOF_CORBA_SHORT");
+               break;
+       case IDLN_TYPE_UNION: {
+               IDL_tree l = IDL_TYPE_UNION (node).switch_body;
+
+               forb_add_align (&max, "FORB_ALIGNOF_CORBA_STRUCT");
+
+               for (; l; l = IDL_LIST (l).next) {
+                       IDL_tree subtype = IDL_MEMBER (IDL_CASE_STMT (
+                               IDL_LIST (l).data).element_spec).type_spec;
+                       max = forb_find_c_align (max, subtype);
+               }
+               break;
+       }
+       case IDLN_EXCEPT_DCL: /* drop through */
+       case IDLN_TYPE_STRUCT: {
+               IDL_tree l = IDL_TYPE_STRUCT (node).member_list;
+                                       
+               for (; l; l = IDL_LIST (l).next) {
+                       IDL_tree member = IDL_MEMBER (IDL_LIST (l).data).type_spec;
+
+                       max = forb_find_c_align (max, member);
+               }
+               break;
+       }
+       case IDLN_TYPE_STRING: /* drop through */
+       case IDLN_TYPE_WIDE_STRING:
+       case IDLN_TYPE_OBJECT:
+       case IDLN_TYPE_TYPECODE:
+       case IDLN_FORWARD_DCL:
+       case IDLN_INTERFACE:
+               forb_add_align (&max, "FORB_ALIGNOF_CORBA_POINTER");
+               break;
+       case IDLN_TYPE_ARRAY: {
+               IDL_tree subtype = IDL_TYPE_DCL (
+                       IDL_get_parent_node (node, IDLN_TYPE_DCL, NULL)).type_spec;
+               max = forb_find_c_align (max, subtype);
+               break;
+       }
+       case IDLN_TYPE_SEQUENCE:
+               forb_add_align (&max, "FORB_ALIGNOF_CORBA_STRUCT");
+               forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG");
+               forb_add_align (&max, "FORB_ALIGNOF_CORBA_POINTER");
+               break;
+       case IDLN_TYPE_ANY:
+               forb_add_align (&max, "FORB_ALIGNOF_CORBA_STRUCT");
+               forb_add_align (&max, "FORB_ALIGNOF_CORBA_POINTER");
+               break;
+       default:
+               g_error ("Can't find alignment %s\n", 
+                        IDL_tree_type_names[IDL_NODE_TYPE (node)]);
+               break;
+       }
+
+       return max;
+}
+
+static void
+forb_output_tcstruct_c_align (FILE *fh, IDL_tree node)
+{
+       GSList *max;
+       GString *str = g_string_sized_new (120);
+
+       max = forb_find_c_align (NULL, node);
+
+       if (!max)
+               g_string_append (str, "1");
+
+       else if (!max->next)
+               g_string_append (str, max->data);
+
+       else {
+               int i = 0;
+               GSList *l;
+
+               for (l = max; l; l = l->next) {
+                       g_string_append (str, "MAX (");
+                       g_string_append (str, l->data);
+                       g_string_append (str, ", ");
+                       i++;
+               }
+               
+               g_string_append (str, "1");
+               for (; i > 0; i--)
+                       g_string_append_c (str, ')');
+       }
+
+       fprintf (fh, "%s", str->str);
+
+       g_string_free (str, TRUE);
+}
+
+static void
+cbe_tc_generate (OIDL_C_Info  *ci,
+                CBETCGenInfo *tci)
+{
+       CBETCGenInfo  subtci;
+       IDL_tree      curitem;
+       char         *ctmp;
+       int           union_default_index = -1,
+                     subnames_id  = random_id++,
+                     subtypes_id  = random_id++,
+                     sublabels_id = random_id++;
+
+       if (strncmp (tci->structname, "anon", 4)) {
+               fprintf (ci->fh, "#if ");
+               forb_cbe_id_cond_hack (ci->fh, "TC_IMPL",
+                                       tci->structname, ci->c_base_name);
+               fprintf (ci->fh, " && !defined(TC_DEF_%s)\n", tci->structname);
+               fprintf (ci->fh, "#define TC_DEF_%s 1\n", tci->structname);
+       }
+
+       if (IDL_NODE_TYPE (tci->ts) == IDLN_TYPE_DCL) {
+               subtci = *tci;
+
+               curitem = IDL_TYPE_DCL (tci->ts).type_spec;
+               subtci.substructname = ctmp = forb_generate_tcstruct_name (curitem);
+
+               /* 
+                * The only type not already defined elsewhere
+                * that can be in the left half of a TypeCode.
+                */
+               if (IDL_NODE_TYPE (curitem) == IDLN_TYPE_SEQUENCE) {
+                       subtci.structname = ctmp;
+                       subtci.ts         = curitem;
+                       cbe_tc_generate (ci, &subtci);
+               }
+
+               for (curitem = IDL_TYPE_DCL (tci->ts).dcls; curitem;
+                    curitem = IDL_LIST (curitem).next) {
+                       subtci.ts = IDL_LIST (curitem).data;
+
+                       if (IDL_NODE_TYPE (subtci.ts) == IDLN_TYPE_ARRAY)
+                               subtci.structname = forb_generate_tcstruct_name (
+                                                       IDL_TYPE_ARRAY (subtci.ts).ident);
+                       else
+                               subtci.structname = forb_generate_tcstruct_name (subtci.ts);
+
+                       cbe_tc_generate (ci, &subtci);
+                       g_free (subtci.structname);
+               }
+
+       g_free (ctmp);
+       return;
+       }
+
+       /* Do magic here - nesting of typecodes for arrays */
+       if (IDL_NODE_TYPE (tci->ts) == IDLN_TYPE_ARRAY && 
+            (IDL_list_length (IDL_TYPE_ARRAY (tci->ts).size_list) > tci->array_gen_ctr)) {
+
+               curitem = IDL_list_nth (IDL_TYPE_ARRAY (tci->ts).size_list,
+                                       tci->array_gen_ctr - 1);
+
+               subtci = *tci;
+               subtci.structname = ctmp = forb_generate_tcstruct_name (curitem);
+               subtci.array_gen_ctr++;
+
+               cbe_tc_generate (ci, &subtci);
+
+               tci->substructname = ctmp; /* FIXME: memory leak */
+       }
+
+       forb_output_tcstruct_anon_subnames_array  (ci->fh, tci->ts, subnames_id);
+       forb_output_tcstruct_anon_subtypes_array  (ci->fh, tci->ts, subtypes_id,
+                                                   tci->substructname);
+
+       union_default_index = forb_output_tcstruct_anon_sublabels_array (
+                                       ci->fh, tci->ts, sublabels_id);
+
+       if (!strncmp (tci->structname, "anon", 4))
+               fprintf (ci->fh, "static ");
+       else {
+               fprintf (ci->fh, "#ifdef FORB_IDL_C_IMODULE_%s\n",
+                        ci->c_base_name);
+               fprintf (ci->fh, "static\n");
+               fprintf (ci->fh, "#endif\n");
+       }
+
+       fprintf (ci->fh, "FORB2_MAYBE_CONST struct CORBA_TypeCode_struct %s_struct = {\n",
+                               tci->structname);
+
+       forb_output_tcstruct_parent (ci->fh);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_kind (ci->fh, tci->ts, tci->array_gen_ctr);
+
+       fprintf (ci->fh, ",\n");
+
+       /* flags */
+       fprintf (ci->fh, "0,\n");
+
+       /* c_length */
+       fprintf (ci->fh, "0,\n");
+
+       forb_output_tcstruct_c_align (ci->fh, tci->ts);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_length (ci->fh, tci->ts, tci->array_gen_ctr);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_sub_parts (ci->fh, tci->ts);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_subtypes (ci->fh, tci->ts, subtypes_id);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_discriminator (ci->fh, tci->ts);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_name (ci->fh, tci->ts, tci->array_gen_ctr);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_repo_id (ci->fh, tci->ts, tci->array_gen_ctr);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_subnames (ci->fh, tci->ts, subnames_id);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_sublabels (ci->fh, tci->ts, sublabels_id);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_default_index (ci->fh, union_default_index);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_recurse_depth (ci->fh);
+
+       fprintf (ci->fh, ",\n");
+
+       forb_output_tcstruct_digits_scale (ci->fh, tci->ts);
+
+       fprintf (ci->fh, "\n};\n");
+
+       if (strncmp (tci->structname, "anon", 4))
+               fprintf (ci->fh, "#endif\n");
+}
diff --git a/src/forb/forb-idl/forb-idl-c-utils.c b/src/forb/forb-idl/forb-idl-c-utils.c
new file mode 100644 (file)
index 0000000..3d8aee6
--- /dev/null
@@ -0,0 +1,837 @@
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+#include <inttypes.h>
+
+/** 
+ * 
+ * 
+ * @param of 
+ * @param ts Type spec.
+ * @param name decl
+ * @param use_name use identifier from name 
+ * @param var_prefix prefix for identifier taken from name
+ * @param serialization 
+ */
+void
+forb_cbe_write_ser_var(FILE *of, IDL_tree ts, IDL_tree name,
+                      bool use_name,
+                      char *var_prefix,
+                      enum forb_ser serialization)
+{
+       int indent = 0, i;
+       GString *id = g_string_new("");
+       char *serialize = (serialization == SERIALIZE) ? "serialize" : "deserialize";
+       gboolean use_ampersand = TRUE;
+
+       switch(IDL_NODE_TYPE(name)) {
+       case IDLN_IDENT:
+               fprintf(of, "  ");
+               if (use_name)
+                       g_string_assign(id, IDL_IDENT(name).str);
+               
+               if (IDL_NODE_TYPE(forb_cbe_get_typespec(ts)) == IDLN_TYPE_ARRAY)
+                 use_ampersand = FALSE;
+
+/*             printf("%s%s:\n", var_prefix, use_name ? id->str:""); */
+/*             forb_idl_print_node(forb_cbe_get_typespec(ts), 2); */
+       
+               break;
+       case IDLN_TYPE_ARRAY:
+       {
+               IDL_tree curitem;
+               char var;
+               if (use_name)
+                       g_string_assign(id, IDL_IDENT(IDL_TYPE_ARRAY(name).ident).str);
+
+               var = 'i';
+               fprintf(of, "  {\n    CORBA_unsigned_long ");
+               for(curitem = IDL_TYPE_ARRAY(name).size_list; curitem; curitem = IDL_LIST(curitem).next) {
+                       fprintf(of, "%c", var);
+                       if (IDL_LIST(curitem).next)
+                               fprintf(of, ", ");
+                       g_string_append_printf(id, "[%c]", var);
+                       var++;
+               }
+               fprintf(of, ";\n");
+
+               var = 'i';
+               for(curitem = IDL_TYPE_ARRAY(name).size_list; curitem; curitem = IDL_LIST(curitem).next) {
+                       indent++;
+                       for (i=0; i<indent+1; i++)
+                               fprintf(of, "  ");
+                       fprintf(of, "for (%c=0; %c<%" PRId64 "; %c++) \n",
+                               var, var, IDL_INTEGER(IDL_LIST(curitem).data).value, var);
+                       var++;
+               }
+
+
+               for (i=0; i<indent+2; i++)
+                       fprintf(of, "  ");
+
+       }
+       break;
+       default:
+               g_error("Weird varname - %s", IDL_tree_type_names[IDL_NODE_TYPE(name)]);
+               break;
+       }
+       fprintf(of, "if (!");
+       forb_cbe_write_typespec(of, ts);
+       fprintf(of, "_%s(codec, %s%s%s)) goto ser_exception;\n",
+               serialize, use_ampersand ? "&":"", var_prefix, id->str);
+       if (indent)
+               fprintf(of, "  }\n");
+
+       g_string_free(id, TRUE);
+}
+
+
+char *
+forb_cbe_get_typecode_name (IDL_tree tree)
+{
+       if (!tree)
+               return g_strdup ("TC_FIXME");
+       else
+               return g_strconcat ("TC_", forb_cbe_get_typespec_str (tree), NULL);
+}
+
+gboolean
+forb_cbe_type_is_builtin(IDL_tree tree)
+{ 
+/*   return FALSE; */
+  switch(IDL_NODE_TYPE(tree)) {
+  case IDLN_LIST:
+  case IDLN_GENTREE:
+  case IDLN_MEMBER:
+  case IDLN_CASE_STMT:
+  case IDLN_MODULE:
+  case IDLN_BINOP:
+  case IDLN_UNARYOP:
+  case IDLN_CODEFRAG:
+    g_error("Strange type for being a builtin");
+    break;
+  case IDLN_INTEGER:
+  case IDLN_STRING:
+  case IDLN_WIDE_STRING:
+  case IDLN_CHAR:
+  case IDLN_WIDE_CHAR:
+  case IDLN_FIXED:
+  case IDLN_FLOAT:
+  case IDLN_BOOLEAN:
+  case IDLN_CONST_DCL:
+  case IDLN_TYPE_INTEGER:
+  case IDLN_TYPE_FLOAT:
+  case IDLN_TYPE_CHAR:
+  case IDLN_TYPE_WIDE_CHAR:
+  case IDLN_TYPE_STRING:
+  case IDLN_TYPE_WIDE_STRING:
+  case IDLN_TYPE_BOOLEAN:
+  case IDLN_TYPE_OCTET:
+  case IDLN_TYPE_ANY:
+  case IDLN_TYPE_OBJECT:
+  case IDLN_TYPE_TYPECODE:
+  case IDLN_TYPE_ENUM:
+  case IDLN_TYPE_SEQUENCE:
+    return TRUE;
+    break;
+  case IDLN_TYPE_DCL:
+  case IDLN_EXCEPT_DCL:
+  case IDLN_ATTR_DCL:
+  case IDLN_OP_DCL:
+  case IDLN_PARAM_DCL:
+  case IDLN_TYPE_FIXED:
+  case IDLN_TYPE_ARRAY:
+  case IDLN_TYPE_STRUCT:
+  case IDLN_TYPE_UNION:
+  case IDLN_IDENT:
+  case IDLN_INTERFACE:
+  case IDLN_FORWARD_DCL:
+  case IDLN_NATIVE:
+  default:
+    return FALSE;
+    break;
+  }
+
+  return FALSE;
+}
+
+/**
+    Gets the "type" of {tree} as known in C.
+    The return value was alloc'd via g_malloc, and must be g_free'd.
+**/
+char *
+forb_cbe_get_typespec_str(IDL_tree tree)
+{
+  char *retval = NULL;
+  GString *tmpstr = NULL;
+
+  if(!tree) {
+    return g_strdup("void");
+  }
+
+  switch(IDL_NODE_TYPE(tree)) {
+  case IDLN_MEMBER:
+    return forb_cbe_get_typespec_str(IDL_MEMBER(tree).type_spec);
+    break;
+  case IDLN_TYPE_ANY:
+    retval = "CORBA_any";
+    break;
+  case IDLN_TYPE_FLOAT:
+    switch(IDL_TYPE_FLOAT(tree).f_type) {
+    case IDL_FLOAT_TYPE_FLOAT:
+      retval = "CORBA_float";
+      break;
+    case IDL_FLOAT_TYPE_DOUBLE:
+      retval = "CORBA_double";
+      break;
+    case IDL_FLOAT_TYPE_LONGDOUBLE:
+      retval = "CORBA_long_double";
+      break;
+    }
+    break;
+  case IDLN_TYPE_FIXED:
+    return g_strdup_printf( "CORBA_fixed_%" PRId64 "_%" PRId64 "",
+                    IDL_INTEGER(IDL_TYPE_FIXED(tree).positive_int_const).value,
+                    IDL_INTEGER(IDL_TYPE_FIXED(tree).integer_lit).value);
+    break;
+  case IDLN_TYPE_INTEGER:
+    tmpstr = g_string_new(NULL);
+    g_string_append(tmpstr, "CORBA_");
+    if(!IDL_TYPE_INTEGER(tree).f_signed)
+       g_string_append(tmpstr, "unsigned_");
+
+    switch(IDL_TYPE_INTEGER(tree).f_type) {
+    case IDL_INTEGER_TYPE_SHORT:
+       g_string_append(tmpstr, "short");
+       break;
+    case IDL_INTEGER_TYPE_LONGLONG:
+       g_string_append(tmpstr, "long_");
+       /* FALLTHROUGH */
+    case IDL_INTEGER_TYPE_LONG:
+       g_string_append(tmpstr, "long");
+       break;
+    }
+    break;
+  case IDLN_TYPE_STRING:
+    retval = "CORBA_string";   /* this is non-standard! */
+    break;
+  case IDLN_TYPE_OCTET:
+    retval = "CORBA_octet";
+    break;
+  case IDLN_TYPE_WIDE_STRING:
+    retval = "CORBA_wstring";  /* this is non-standard! */
+    break;
+  case IDLN_TYPE_CHAR:
+    retval = "CORBA_char";
+    break;
+  case IDLN_TYPE_WIDE_CHAR:
+    retval = "CORBA_wchar";
+    break;
+  case IDLN_TYPE_BOOLEAN:
+    retval = "CORBA_boolean";
+    break;
+  case IDLN_TYPE_STRUCT:
+    return forb_cbe_get_typespec_str(IDL_TYPE_STRUCT(tree).ident);
+  case IDLN_EXCEPT_DCL:
+    return forb_cbe_get_typespec_str(IDL_EXCEPT_DCL(tree).ident);
+  case IDLN_TYPE_ARRAY:
+    return forb_cbe_get_typespec_str(IDL_TYPE_ARRAY(tree).ident);
+  case IDLN_TYPE_UNION:
+    return forb_cbe_get_typespec_str(IDL_TYPE_UNION(tree).ident);
+  case IDLN_TYPE_ENUM:
+    return forb_cbe_get_typespec_str(IDL_TYPE_ENUM(tree).ident);
+  case IDLN_IDENT:
+    return IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0);
+  case IDLN_PARAM_DCL:
+    return forb_cbe_get_typespec_str(IDL_PARAM_DCL(tree).param_type_spec);
+  case IDLN_TYPE_SEQUENCE:
+    {
+       IDL_tree subtype = IDL_TYPE_SEQUENCE(tree).simple_type_spec;
+        char *ctmp, *base;
+        ctmp = forb_cbe_get_typespec_str(subtype);
+       /* We should have built-in alias to make this next line not needed */
+       base = forb_cbe_type_is_builtin(subtype)
+         ? ctmp + strlen("CORBA_") : ctmp;
+       retval = g_strdup_printf( "CORBA_sequence_%s", base);
+        g_free(ctmp);
+        return retval;
+    }
+    break;
+  case IDLN_NATIVE:
+    retval = forb_cbe_get_typespec_str(IDL_NATIVE(tree).ident);
+    break;
+  case IDLN_FORWARD_DCL:
+  case IDLN_INTERFACE:
+    return forb_cbe_get_typespec_str(IDL_INTERFACE(tree).ident);
+  case IDLN_TYPE_OBJECT:
+    retval = "CORBA_Object";
+    break;
+  case IDLN_TYPE_TYPECODE:
+    retval = "CORBA_TypeCode";
+    break;
+  default:
+    g_error("We were asked to get a typename for a %s",
+           IDL_tree_type_names[IDL_NODE_TYPE(tree)]);
+    break;
+  }
+
+  if (retval)
+    return g_strdup (retval);
+  else
+    return g_string_free (tmpstr, FALSE);
+}
+
+void
+forb_cbe_write_typespec(FILE *of, IDL_tree tree)
+{
+    char *name = forb_cbe_get_typespec_str(tree);
+    fprintf( of, name);
+    g_free(name);
+}
+
+/**
+    Parameters (e.g., arguments to methods, and the return value
+    have some complicated rules in the C mapping for how many
+    levels of pointer and the exact type involved. This function
+    generates the externally visible parameter type.
+
+    Note the hack below because "const CORBA_string" is not
+    promotable to "const CORBA_char*" (the later the standard
+    to which apps are written, while the former is what would
+    be produced without the hack).
+**/
+static char *
+forb_cbe_write_param_typespec_str(IDL_tree ts, IDL_ParamRole role)
+{
+       int      i, n;
+       gboolean isSlice;
+       char    *name;
+       GString *str = g_string_sized_new (23);
+       IDL_tree typedef_spec;
+       char *typedef_name;
+
+       n = oidl_param_info (ts, role, &isSlice);
+       name = forb_cbe_get_typespec_str (ts);
+
+       if ( role == DATA_IN ) {
+               /* We want to check if this is a typedef for CORBA_string so we can do special handling 
+                * in that case. 
+                */
+               typedef_spec = forb_cbe_get_typespec (ts);
+               typedef_name = forb_cbe_get_typespec_str (typedef_spec);
+
+               g_string_printf (str, "const %s", 
+                                !strcmp (typedef_name, "CORBA_string") ?
+                                "CORBA_char *" : name);
+
+               g_free (typedef_name);
+       } else
+               g_string_printf (str, "%s", name);
+
+       g_free (name);
+
+       if ( isSlice )
+               g_string_append (str, "_slice");
+
+       for (i = 0; i < n; i++)
+               g_string_append_c (str, '*');
+
+       return g_string_free (str, FALSE);
+}
+
+static void
+forb_cbe_write_param_typespec_raw (FILE *of, IDL_tree ts, IDL_ParamRole role)
+{
+    char *str;
+    str = forb_cbe_write_param_typespec_str (ts, role);
+    fprintf (of, str);
+    g_free (str);
+}
+
+void
+forb_cbe_write_param_typespec(FILE *of, IDL_tree tree) {
+    IDL_tree           ts = NULL /* Quiet gcc */;
+    IDL_ParamRole      role = 0 /* Quiet gcc */;
+
+    switch ( IDL_NODE_TYPE(tree) ) {
+    case IDLN_OP_DCL: /* means return value of method */
+        ts = IDL_OP_DCL(tree).op_type_spec;
+       role = DATA_RETURN;
+        break;
+    case IDLN_PARAM_DCL: /* one of the parameters */
+        ts = IDL_PARAM_DCL(tree).param_type_spec;
+       role = oidl_attr_to_paramrole(IDL_PARAM_DCL(tree).attr);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    forb_cbe_write_param_typespec_raw(of, ts, role);
+}
+
+void
+forb_cbe_op_write_proto (FILE       *of,
+                         IDL_tree    op,
+                         const char *nom_prefix,
+                         gboolean    for_epv)
+{
+       IDL_tree  sub;
+       char     *id;
+
+       g_assert (IDL_NODE_TYPE(op) == IDLN_OP_DCL);
+
+       forb_cbe_write_param_typespec (of, op);
+
+       id = IDL_ns_ident_to_qstring (
+               IDL_IDENT_TO_NS (IDL_INTERFACE (
+                       IDL_get_parent_node (op, IDLN_INTERFACE, NULL)).ident), "_", 0);
+
+       if (for_epv)
+               fprintf (of, "\t(*%s%s)", nom_prefix ? nom_prefix : "",
+                        IDL_IDENT(IDL_OP_DCL(op).ident).str);
+       else 
+               fprintf (of, " %s%s_%s", nom_prefix ? nom_prefix : "",
+                        id, IDL_IDENT (IDL_OP_DCL (op).ident).str);
+
+       fprintf (of, "(");
+
+/*     if (for_epv) */
+/*             fprintf (of, "PortableServer_Servant _servant, "); */
+/*     else */
+               fprintf (of, "%s _obj, ", id);
+
+       g_free (id);
+
+       for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+               IDL_tree parm = IDL_LIST (sub).data;
+
+               forb_cbe_write_param_typespec (of, parm);
+
+               fprintf (of, " %s, ", IDL_IDENT (IDL_PARAM_DCL (parm).simple_declarator).str);
+       }
+
+       if (IDL_OP_DCL (op).context_expr)
+               fprintf (of, "CORBA_Context _ctx, ");
+
+       fprintf (of, "CORBA_Environment *ev)");
+}
+
+/* Writes the value of the constant in 'tree' to file handle 'of' */
+static char *
+forb_cbe_get_const(IDL_tree tree)
+{
+  char *opc = NULL, *retval, *ctmp;
+  GString *tmpstr = g_string_new(NULL);
+
+  switch(IDL_NODE_TYPE(tree)) {
+  case IDLN_BOOLEAN:
+    g_string_printf(tmpstr, "%s", IDL_BOOLEAN(tree).value?"CORBA_TRUE":"CORBA_FALSE");
+    break;
+  case IDLN_CHAR:
+    g_string_printf(tmpstr, "'\\x%X'", *(unsigned char *)IDL_CHAR(tree).value);
+    break;
+  case IDLN_FLOAT:
+    g_string_printf(tmpstr, "%f", IDL_FLOAT(tree).value);
+    break;
+  case IDLN_INTEGER:
+    g_string_printf(tmpstr, "%" PRId64 "", IDL_INTEGER(tree).value);
+    break;
+  case IDLN_STRING:
+    g_string_printf(tmpstr, "\"%s\"", IDL_STRING(tree).value);
+    break;
+  case IDLN_WIDE_CHAR:
+    g_string_printf(tmpstr, "L'%ls'", IDL_WIDE_CHAR(tree).value);
+    break;
+  case IDLN_WIDE_STRING:
+    g_string_printf(tmpstr, "L\"%ls\"", IDL_WIDE_STRING(tree).value);
+    break;
+  case IDLN_BINOP:
+    g_string_printf(tmpstr, "(");
+    ctmp = forb_cbe_get_const(IDL_BINOP(tree).left);
+    g_string_append(tmpstr, ctmp);
+    g_free(ctmp);
+    switch(IDL_BINOP(tree).op) {
+    case IDL_BINOP_OR:
+      opc = "|";
+      break;
+    case IDL_BINOP_XOR:
+      opc = "^";
+      break;
+    case IDL_BINOP_AND:
+      opc = "&";
+      break;
+    case IDL_BINOP_SHR:
+      opc = ">>";
+      break;
+    case IDL_BINOP_SHL:
+      opc = "<<";
+      break;
+    case IDL_BINOP_ADD:
+      opc = "+";
+      break;
+    case IDL_BINOP_SUB:
+      opc = "-";
+      break;
+    case IDL_BINOP_MULT:
+      opc = "*";
+      break;
+    case IDL_BINOP_DIV:
+      opc = "/";
+      break;
+    case IDL_BINOP_MOD:
+      opc = "%";
+      break;
+    }
+    g_string_append_printf(tmpstr, " %s ", opc);
+    ctmp = forb_cbe_get_const(IDL_BINOP(tree).right);
+    g_string_append_printf(tmpstr, "%s)", ctmp);
+    g_free(ctmp);
+    break;
+  case IDLN_UNARYOP:
+    switch(IDL_UNARYOP(tree).op) {
+    case IDL_UNARYOP_PLUS: opc = "+"; break;
+    case IDL_UNARYOP_MINUS: opc = "-"; break;
+    case IDL_UNARYOP_COMPLEMENT: opc = "~"; break;
+    }
+    ctmp = forb_cbe_get_const(IDL_UNARYOP(tree).operand);
+    g_string_printf(tmpstr, "%s%s", opc, ctmp);
+    g_free(ctmp);
+    break;
+  case IDLN_IDENT:
+    {
+      char *id;
+      id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0);
+      g_string_printf(tmpstr, "%s", id);
+      g_free(id);
+    }
+    break;
+  default:
+    g_error("We were asked to print a constant for %s", IDL_tree_type_names[tree->_type]);
+    break;
+  }
+
+  retval = tmpstr->str;
+
+  g_string_free(tmpstr, FALSE);
+
+  return retval;
+}
+
+void
+forb_cbe_write_const(FILE *of, IDL_tree tree)
+{
+  char *ctmp;
+
+  ctmp = forb_cbe_get_const(tree);
+  fprintf(of, "%s", ctmp);
+  g_free(ctmp);
+}
+
+/* This is the WORST HACK in the WORLD, really truly, but the C preprocessor doesn't allow us to use
+   strings, so we have to work around it by using individual characters. */
+void
+forb_cbe_id_define_hack(FILE *fh, const char *def_prefix, const char *def_name, const char *def_value)
+{
+  int i, n;
+  n = strlen(def_value);
+  for(i = 0; i < n; i++)
+    fprintf(fh, "#define %s_%s_%d '%c'\n", def_prefix, def_name, i, def_value[i]);
+}
+
+void
+forb_cbe_id_cond_hack(FILE *fh, const char *def_prefix, const char *def_name, const char *def_value)
+{
+  int i, n;
+  n = strlen(def_value);
+  if(n <= 0)
+    return;
+
+  fprintf(fh, "(");
+
+  for(i = 0; i < n; i++)
+    fprintf(fh, "%s (%s_%s_%d == '%c') \\\n", i?"&&":"", def_prefix, def_name, i, def_value[i]);
+  fprintf(fh, ")");
+}
+
+#define BASE_TYPES \
+            IDLN_TYPE_INTEGER: \
+       case IDLN_TYPE_FLOAT: \
+       case IDLN_TYPE_ENUM: \
+        case IDLN_TYPE_BOOLEAN: \
+       case IDLN_TYPE_CHAR: \
+       case IDLN_TYPE_WIDE_CHAR: \
+       case IDLN_TYPE_OCTET
+
+#define STRING_TYPES \
+            IDLN_TYPE_STRING: \
+       case IDLN_TYPE_WIDE_STRING
+
+#define OBJREF_TYPES \
+            IDLN_TYPE_OBJECT: \
+       case IDLN_INTERFACE: \
+       case IDLN_FORWARD_DCL
+
+static const char *
+forb_cbe_flatten_ref (IDL_ParamRole role, IDL_tree typespec)
+{
+       gboolean is_fixed;
+
+       is_fixed = forb_cbe_type_is_fixed_length (typespec);
+
+       switch (role) {
+       case DATA_IN:
+               switch (IDL_NODE_TYPE (typespec)) {
+               case BASE_TYPES:
+               case STRING_TYPES:
+               case OBJREF_TYPES:
+               case IDLN_TYPE_TYPECODE:
+               case IDLN_NATIVE:
+                       return "(gpointer)&";
+
+               case IDLN_TYPE_STRUCT:
+               case IDLN_TYPE_UNION:
+               case IDLN_TYPE_ANY:
+               case IDLN_TYPE_SEQUENCE:
+               case IDLN_TYPE_ARRAY:
+                       return "(gpointer)";
+                       
+               default:
+               case IDLN_TYPE_FIXED:
+                       g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+               };
+               return NULL;
+
+       case DATA_INOUT:
+               switch (IDL_NODE_TYPE (typespec)) {
+               case BASE_TYPES:
+               case STRING_TYPES:
+               case OBJREF_TYPES:
+               case IDLN_TYPE_TYPECODE:
+               case IDLN_TYPE_STRUCT:
+               case IDLN_TYPE_UNION:
+               case IDLN_TYPE_ARRAY:
+               case IDLN_NATIVE:
+               case IDLN_TYPE_ANY:
+               case IDLN_TYPE_SEQUENCE:
+                       return "";
+
+               default:
+               case IDLN_TYPE_FIXED:
+                       g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+               };
+               return NULL;
+
+       case DATA_OUT:
+               switch (IDL_NODE_TYPE (typespec)) {
+               case BASE_TYPES:
+               case STRING_TYPES:
+               case OBJREF_TYPES:
+               case IDLN_TYPE_TYPECODE:
+               case IDLN_NATIVE:
+                       return "&";
+
+               case IDLN_TYPE_STRUCT:
+               case IDLN_TYPE_UNION:
+               case IDLN_TYPE_ARRAY:
+                       if (is_fixed)
+                               return "&";
+                       else /* drop through */
+
+               case IDLN_TYPE_SEQUENCE:
+               case IDLN_TYPE_ANY:
+                       return "";
+
+               default:
+               case IDLN_TYPE_FIXED:
+                       g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+               };
+               return NULL;
+
+       case DATA_RETURN:
+               g_error ("No data return handler");
+               return NULL;
+       }
+
+       return NULL;
+}
+
+void
+forb_cbe_flatten_args (IDL_tree tree, FILE *of, const char *name)
+{
+       int i = 0;
+       IDL_tree l;
+
+       for (l = IDL_OP_DCL(tree).parameter_dcls; l;
+            l = IDL_LIST(l).next)
+               i++;
+
+       fprintf (of, "gpointer %s[%d];\n", name, i);
+       
+       i = 0;
+       for (l = IDL_OP_DCL(tree).parameter_dcls; l;
+            l = IDL_LIST(l).next) {
+               IDL_tree decl = IDL_LIST (l).data;
+               IDL_tree tspec = forb_cbe_get_typespec (decl);
+               IDL_ParamRole r = 0;
+
+               switch(IDL_PARAM_DCL(decl).attr) {
+               case IDL_PARAM_IN:    r = DATA_IN;    break;
+               case IDL_PARAM_INOUT: r = DATA_INOUT; break;
+               case IDL_PARAM_OUT:   r = DATA_OUT;   break;
+               default:
+                       g_error("Unknown IDL_PARAM type");
+               }
+               
+               fprintf (of, "%s[%d] = %s%s;\n",
+                        name, i,
+                        forb_cbe_flatten_ref (r, tspec),
+                        IDL_IDENT (IDL_PARAM_DCL (decl).simple_declarator).str);
+               i++;
+       }
+}
+
+static char *
+forb_cbe_unflatten_ref (IDL_ParamRole role, IDL_tree typespec)
+{
+       gboolean is_fixed;
+       char    *typestr;
+       char    *retval;
+
+       is_fixed = forb_cbe_type_is_fixed_length (typespec);
+
+       typestr = forb_cbe_write_param_typespec_str (typespec, role);
+
+       switch (role) {
+       case DATA_IN:
+               switch (IDL_NODE_TYPE (typespec)) {
+               case BASE_TYPES:
+               case STRING_TYPES:
+               case OBJREF_TYPES:
+               case IDLN_TYPE_TYPECODE:
+               case IDLN_NATIVE:
+                       retval = g_strdup_printf ("*(%s *)", typestr);
+                       break;
+
+
+               case IDLN_TYPE_ARRAY:
+                       retval = g_strdup_printf ("(%s_slice *)", typestr);
+                       break;
+
+               case IDLN_TYPE_STRUCT:
+               case IDLN_TYPE_UNION:
+               case IDLN_TYPE_ANY:
+               case IDLN_TYPE_SEQUENCE:
+                       retval = g_strdup_printf ("(%s)", typestr);
+                       break;
+                       
+               default:
+               case IDLN_TYPE_FIXED:
+                       g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+                       retval = NULL;
+                       break;
+               };
+               break;
+
+       case DATA_INOUT:
+               switch (IDL_NODE_TYPE (typespec)) {
+               case IDLN_TYPE_ARRAY:
+                       retval = g_strdup_printf ("(%s_slice *)", typestr);
+                       break;
+
+               case BASE_TYPES:
+               case STRING_TYPES:
+               case OBJREF_TYPES:
+               case IDLN_TYPE_TYPECODE:
+               case IDLN_TYPE_STRUCT:
+               case IDLN_TYPE_UNION:
+               case IDLN_NATIVE:
+               case IDLN_TYPE_ANY:
+               case IDLN_TYPE_SEQUENCE:
+                       retval = g_strdup_printf ("(%s)", typestr);
+                       break;
+
+               default:
+               case IDLN_TYPE_FIXED:
+                       g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+                       retval = NULL;
+                       break;
+               };
+               break;
+
+       case DATA_OUT:
+               switch (IDL_NODE_TYPE (typespec)) {
+               case BASE_TYPES:
+               case STRING_TYPES:
+               case OBJREF_TYPES:
+               case IDLN_TYPE_TYPECODE:
+               case IDLN_NATIVE:
+                       retval = g_strdup_printf ("*(%s *)", typestr);
+                       break;
+
+               case IDLN_TYPE_ARRAY:
+                       if (is_fixed) {
+                               retval = g_strdup_printf ("*(%s_slice **)", typestr);
+                               break;
+                       }
+                       /* drop through */
+
+               case IDLN_TYPE_STRUCT:
+               case IDLN_TYPE_UNION:
+                       if (is_fixed) {
+                               retval = g_strdup_printf ("*(%s *)", typestr);
+                               break;
+                       }
+                       /* drop through */
+
+               case IDLN_TYPE_SEQUENCE:
+               case IDLN_TYPE_ANY:
+                       retval = g_strdup_printf ("(%s)", typestr);
+                       break;
+
+               default:
+               case IDLN_TYPE_FIXED:
+                       g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+                       retval = NULL;
+                       break;
+               };
+               break;
+
+       case DATA_RETURN:
+       default:
+               g_error ("No data return handler");
+               retval = NULL;
+               break;
+       }
+
+       g_free (typestr);
+
+       return retval;
+}
+
+void
+forb_cbe_unflatten_args (IDL_tree tree, FILE *of, const char *name)
+{
+       IDL_tree l;
+       int      i = 0;
+
+       for (l = IDL_OP_DCL(tree).parameter_dcls; l;
+            l = IDL_LIST(l).next) {
+               IDL_tree decl = IDL_LIST (l).data;
+               IDL_tree tspec = forb_cbe_get_typespec (decl);
+               IDL_ParamRole r = 0;
+               char *unflatten;
+
+               switch(IDL_PARAM_DCL(decl).attr) {
+               case IDL_PARAM_IN:    r = DATA_IN;    break;
+               case IDL_PARAM_INOUT: r = DATA_INOUT; break;
+               case IDL_PARAM_OUT:   r = DATA_OUT;   break;
+               default:
+                       g_error("Unknown IDL_PARAM type");
+               }
+
+               unflatten = forb_cbe_unflatten_ref (r, tspec);
+               fprintf (of, "%s%s[%d], ", unflatten, name, i++);
+               g_free (unflatten);
+       }
+}
diff --git a/src/forb/forb-idl/forb-idl-driver.c b/src/forb/forb-idl/forb-idl-driver.c
new file mode 100644 (file)
index 0000000..adc860f
--- /dev/null
@@ -0,0 +1,100 @@
+/**************************************************************************
+
+    forb-idl-driver.c (Dispatch parsed tree to various backends)
+
+    Copyright (C) 1999 Elliot Lee
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    $Id: forb-idl-driver.c 1302 2002-09-04 10:38:18Z mmclouglin $
+
+***************************************************************************/
+
+#include "config.h"
+
+#include "forb-idl2.h"
+#include "forb-idl-backend.h"
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+
+static void
+forb_idl_tree_fake_ops (IDL_tree tree, IDL_ns ns)
+{
+       IDL_tree node;
+
+       if (!tree)
+               return;
+
+       switch(IDL_NODE_TYPE(tree)) {
+       case IDLN_MODULE:
+               forb_idl_tree_fake_ops (IDL_MODULE (tree).definition_list, ns);
+               break;
+       case IDLN_INTERFACE:
+               forb_idl_tree_fake_ops (IDL_INTERFACE (tree).body, ns);
+               break;
+       case IDLN_LIST:
+               for (node = tree; node; node = IDL_LIST (node).next)
+                       forb_idl_tree_fake_ops (IDL_LIST (node).data, ns);
+               break;
+       case IDLN_ATTR_DCL:
+               forb_idl_attr_fake_ops (tree, ns);
+               break;
+       default:
+               break;
+       }
+}
+
+gboolean
+forb_idl_to_backend (const char    *filename,
+                     OIDL_Run_Info *rinfo)
+{
+       IDL_ns   ns;
+       IDL_tree tree;
+       int      errcode;
+       gboolean retval;
+
+       errcode = IDL_parse_filename (
+                       filename, rinfo->cpp_args, NULL,
+                       &tree, &ns,
+                       (rinfo->show_cpp_errors ? IDLF_SHOW_CPP_ERRORS : 0) |
+                       (rinfo->is_pidl ? IDLF_XPIDL : 0) |
+                       (rinfo->onlytop ? IDLF_INHIBIT_INCLUDES : 0) |
+                       IDLF_TYPECODES |
+                       IDLF_SRCFILES |
+                       IDLF_CODEFRAGS,
+                       rinfo->idl_warn_level);
+
+       rinfo->ns = ns;
+
+       if (rinfo->debug_level > 3)
+               forb_idl_print_node (tree, 0);
+
+       if (errcode != IDL_SUCCESS) {
+               if (errcode == -1)
+                       g_warning ("Parse of %s failed: %s", filename, g_strerror (errno));
+
+               return 0;
+       }
+
+       forb_idl_tree_fake_ops (tree, ns);
+
+       if (!strcmp (rinfo->output_language, "c")) 
+               retval = forb_idl_output_c (tree, rinfo);
+//     else
+//             retval = forb_idl_backend_output (rinfo, tree);
+
+       return retval;
+}
diff --git a/src/forb/forb-idl/forb-idl-main.c b/src/forb/forb-idl/forb-idl-main.c
new file mode 100644 (file)
index 0000000..d872360
--- /dev/null
@@ -0,0 +1,297 @@
+/**************************************************************************
+
+    forb-idl-main.c (Driver program for the IDL parser & backend)
+
+    Copyright (C) 1999 Elliot Lee
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    $Id: forb-idl-main.c 2060 2008-05-19 21:11:07Z tml $
+
+***************************************************************************/
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <glib.h>
+#include <libIDL/IDL.h>
+#include <glib/goption.h>
+#include <glib/gi18n.h>
+#include "forb_config.h"
+
+#include "forb-idl2.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* FIXME: this program doesn't seem to support i18n? */
+#ifndef GETTEXT_PACKAGE
+#define GETTEXT_PACKAGE NULL
+#endif
+
+/* Settings made from the command line (prefaced with cl_) */
+static gboolean cl_disable_stubs = FALSE,
+  cl_disable_skels = FALSE,
+  cl_disable_common = FALSE,
+  cl_disable_headers = FALSE;
+  /* cl_enable_skeleton_impl = FALSE */
+static int cl_idlwarnlevel = 2;
+static int cl_debuglevel = 0;
+static int cl_is_pidl = 0;
+static int cl_disable_idata = 0;
+/* static int cl_enable_imodule = 0; */
+/* static int cl_add_imodule = 0; */
+static gboolean cl_disable_defs_skels = FALSE;
+static gboolean cl_showcpperrors = FALSE;
+static char *cl_output_lang = "c";
+static char *cl_include = NULL;
+static char *cl_header_guard_prefix = "";
+static char *cl_backend_dir = NULL;
+static gboolean cl_onlytop = TRUE;
+static char *cl_deps_file = NULL;
+static char *cl_output_directory = "";
+static char **idl_files = NULL;
+
+#define BASE_CPP_ARGS "-D__FORB_IDL__ "
+static GString *cl_cpp_args;
+
+/* Callbacks for goption */
+
+static gboolean
+cl_libIDL_version_callback (const char *option_name,
+                           const char *value,
+                           gpointer data,
+                           GError **error)
+{
+  g_print("libIDL %s (CORBA %s)\n",
+         IDL_get_libver_string(),
+         IDL_get_IDLver_string());
+  exit(0);
+}
+
+static gboolean
+cl_cpp_define_callback (const char *option_name,
+                       const char *value,
+                       gpointer data,
+                       GError **error)
+{
+  g_string_append_printf (cl_cpp_args, "-D%s ", value);
+  return TRUE;
+}
+
+static gboolean
+cl_cpp_include_callback (const char *option_name,
+                        const char *value,
+                        gpointer data,
+                        GError **error)
+{
+  g_string_append_printf (cl_cpp_args, "-I%s ", value);
+  return TRUE;
+}
+
+static gboolean
+cl_version_callback (const char *option_name,
+                    const char *value,
+                    gpointer data,
+                    GError **error)
+{
+  g_print ("forb-idl-2 %s - serial %d\n",
+           VERSION, FORB_CONFIG_SERIAL);
+  exit(0);
+}
+
+/* static gboolean */
+/* cl_c_output_formatter_callback (const char *option_name, */
+/*                             const char *value, */
+/*                             gpointer data, */
+/*                             GError **error) */
+/* { */
+/*   g_warning ("Do not use the 'c-output-formatter' option. It is ignored and will soon go away."); */
+/*   return TRUE; */
+/* } */
+
+static const GOptionEntry cl_libIDL_goptions[] = {
+  { "libIDL-version", 0, 0, G_OPTION_ARG_CALLBACK, cl_libIDL_version_callback, N_("Show version of libIDL used"), NULL },
+  { NULL }
+};
+
+static const GOptionEntry cl_cpp_goptions[] = {
+  { "define", 'D', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_CALLBACK, cl_cpp_define_callback, N_("Define value in preprocessor"), N_("DEFINE") },
+  { "include", 'I', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_CALLBACK, cl_cpp_include_callback, N_("Add search path for include files"), N_("DIR") },
+  { NULL }
+};
+
+static const GOptionEntry goptions[] = {
+  { "version", 'v', 0, G_OPTION_ARG_CALLBACK, cl_version_callback, N_("Output compiler version and serial"), NULL },
+  { "lang", 'l', 0, G_OPTION_ARG_STRING, &cl_output_lang, N_("Output language (default is C)"), N_("LANG") },
+  { "debug", 'd', 0, G_OPTION_ARG_INT, &cl_debuglevel, N_("Debug level (0 to 4)"), N_("LEVEL") },
+  { "idlwarnlevel", 0, 0, G_OPTION_ARG_INT, &cl_idlwarnlevel, N_("IDL warning level (0 to 4, default is 2)"), N_("LEVEL") },
+  { "showcpperrors", 0, 0, G_OPTION_ARG_NONE, &cl_showcpperrors, N_("Show CPP errors"), NULL },
+  { "nostubs", 0, 0, G_OPTION_ARG_NONE, &cl_disable_stubs, N_("Don't output stubs"), NULL },
+  { "noskels", 0, 0, G_OPTION_ARG_NONE, &cl_disable_skels, N_("Don't output skels"), NULL },
+  { "nocommon", 0, 0, G_OPTION_ARG_NONE, &cl_disable_common, N_("Don't output common"), NULL },
+  { "noheaders", 0, 0, G_OPTION_ARG_NONE, &cl_disable_headers, N_("Don't output headers"), NULL },
+  { "include", 0, 0, G_OPTION_ARG_STRING, &cl_include, N_("Put #include <FILE> to the generated header (for native types)"), N_("FILE") },
+/*   { "noidata", 0, 0, G_OPTION_ARG_NONE, &cl_disable_idata, N_("Don't generate Interface type data"), NULL }, */
+/*   { "imodule", 'i', 0, G_OPTION_ARG_NONE, &cl_enable_imodule, N_("Output only an imodule file"), NULL }, */
+/*   { "add-imodule", 0, 0, G_OPTION_ARG_NONE, &cl_add_imodule, N_("Output an imodule file"), NULL }, */
+/*   { "skeleton-impl", 0, 0, G_OPTION_ARG_NONE, &cl_enable_skeleton_impl, N_("Output skeleton implementation"), NULL }, */
+  { "backenddir", 0, 0, G_OPTION_ARG_FILENAME, &cl_backend_dir, N_("Override IDL backend library directory"), N_("DIR") },
+/*   { "c-output-formatter", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, &cl_c_output_formatter_callback, "DEPRECATED and IGNORED", "PROGRAM" }, */
+  { "onlytop", 0, 0, G_OPTION_ARG_NONE, &cl_onlytop, N_("Inhibit includes"), NULL },
+  { "pidl", 0, 0, G_OPTION_ARG_NONE, &cl_is_pidl, N_("Treat as Pseudo IDL"), NULL },
+  { "nodefskels", 0, 0, G_OPTION_ARG_NONE, &cl_disable_defs_skels, N_("Don't output defs for skels in header"), NULL },
+  { "deps", 0, 0,  G_OPTION_ARG_FILENAME, &cl_deps_file, N_("Generate dependency info suitable for inclusion in Makefile"), N_("FILENAME") },
+  { "headerguardprefix", 0, 0, G_OPTION_ARG_STRING, &cl_header_guard_prefix, N_("Prefix for #ifdef header guards. Sometimes useful to avoid conflicts."), N_("PREFIX") },
+  { "output-dir", 0, 0, G_OPTION_ARG_FILENAME, &cl_output_directory, N_("Where to put generated files. This directory must exist."), N_("DIR") },
+  { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &idl_files, NULL, N_("<IDL files>") },
+  { NULL }
+};
+
+/********** main routines **********/
+int main(int argc, char *argv[])
+{
+  GOptionContext *context;
+  GOptionGroup *group;
+  GError *error = NULL;
+  OIDL_Run_Info rinfo;
+  GPtrArray *args;
+  int retval = 0;
+  gboolean result;
+  gpointer freeme;
+  guint i;
+
+  /* Argument parsing, etc. */
+  cl_cpp_args = g_string_new("-D__FORB_IDL__ ");
+
+  /* GOption cannot parse single-letter options without space
+   * between option and argument (-I../dir) or single-dash options.
+   * So fix those up before parsing, to retain command line compatibility
+   * with previous popt based versions of forb-idl-2
+   */
+  args = g_ptr_array_sized_new (2 * argc);
+  g_ptr_array_add (args, g_strdup (argv[0]));
+
+  for (i = 1; i < argc; ++i) {
+    if (argv[i][0] == '-' &&
+       (argv[i][1] == 'D' || argv[i][1] == 'I') &&
+       argv[i][2] != '\0') {
+      g_ptr_array_add (args, g_strndup (argv[i], 2));
+      g_ptr_array_add (args, g_strdup (argv[i] + 2));
+    } else if (strcmp (argv[i], "-define") == 0 ||
+               strcmp (argv[i], "-include") == 0) {
+      g_ptr_array_add (args, g_strdup_printf ("-%s", argv[i]));
+    } else {
+      g_ptr_array_add (args, g_strdup (argv[i]));
+    }
+  }
+
+  /* Parsing will modify the array; memdup it beforehand
+   * so we can free it correctly
+   */
+  argc = args->len;
+  argv = freeme = g_memdup (args->pdata, argc * sizeof (gpointer));
+  g_ptr_array_add (args, NULL); /* so we can use g_strfreev */
+
+  /* Now parse the options */
+  context = g_option_context_new ("");
+  g_option_context_add_main_entries (context, goptions, GETTEXT_PACKAGE);
+
+  group = g_option_group_new ("libIDL", N_("libIDL options"), N_("Show libIDL options"), NULL, NULL);
+  g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
+  g_option_group_add_entries (group, cl_libIDL_goptions);
+  g_option_context_add_group (context, group);
+
+  group = g_option_group_new ("cpp", N_("Preprocessor options"), N_("Show preprocessor options"), NULL, NULL);
+  g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
+  g_option_group_add_entries (group, cl_cpp_goptions);
+  g_option_context_add_group (context, group);
+
+  result = g_option_context_parse (context, &argc, &argv, &error);
+  g_option_context_free (context);
+  g_strfreev ((char **) g_ptr_array_free (args, FALSE));
+  g_free (freeme);
+
+  if (!result) {
+    g_print ("forb-idl-2: %s\n", error->message);
+    g_error_free (error);
+    exit (1);
+  }
+
+  if (!idl_files) {
+    g_print ("No input files given!\n");
+    exit (1);
+  }
+
+  /* Prep our run info for the backend */
+  rinfo.cpp_args = cl_cpp_args->str;
+  rinfo.debug_level = cl_debuglevel;
+  rinfo.idl_warn_level = cl_idlwarnlevel;
+  rinfo.show_cpp_errors = cl_showcpperrors;
+  rinfo.is_pidl = cl_is_pidl;
+  rinfo.do_skel_defs = !cl_disable_defs_skels;
+  rinfo.enabled_passes =
+     (cl_disable_stubs?0:OUTPUT_STUBS)
+    |(cl_disable_skels?0:OUTPUT_SKELS)
+    |(cl_disable_common?0:OUTPUT_COMMON)
+    |(cl_disable_headers?0:OUTPUT_HEADERS)
+/*     |(cl_enable_skeleton_impl?OUTPUT_SKELIMPL:0) */
+/*     |(cl_add_imodule?OUTPUT_IMODULE:0) */
+    |(cl_deps_file != NULL?OUTPUT_DEPS:0)
+    ;
+
+  rinfo.deps_file = cl_deps_file;
+
+/*   if (cl_enable_imodule) /\* clobber *\/ */
+/*     rinfo.enabled_passes = */
+/*       OUTPUT_COMMON | OUTPUT_HEADERS | OUTPUT_IMODULE; */
+
+  rinfo.output_language = cl_output_lang;
+  rinfo.header_guard_prefix = cl_header_guard_prefix;
+  rinfo.include = cl_include;
+  rinfo.output_directory = cl_output_directory;
+  rinfo.backend_directory = cl_backend_dir;
+  rinfo.onlytop = cl_onlytop;
+  rinfo.idata = !cl_disable_idata;
+
+  if (cl_debuglevel) {
+  printf ("forb-idl-2 " VERSION " compiling\n");
+  printf (" %s mode, %s preprocessor errors, passes: %s%s%s%s%s%s\n\n",
+         rinfo.is_pidl ? "pidl" : "",
+         rinfo.show_cpp_errors ? "show" : "hide",
+         rinfo.enabled_passes&OUTPUT_STUBS ? "stubs " : "",
+         rinfo.enabled_passes&OUTPUT_SKELS ? "skels " : "",
+         rinfo.enabled_passes&OUTPUT_COMMON ? "common " : "",
+         rinfo.enabled_passes&OUTPUT_HEADERS ? "headers " : "",
+         rinfo.enabled_passes&OUTPUT_SKELIMPL ? "skel_impl " : "",
+         rinfo.enabled_passes&OUTPUT_IMODULE ? "imodule" : "");
+  }
+  
+  /* Do it */
+  for (i = 0; idl_files[i]; ++i) {
+    if (cl_debuglevel) g_print ("Processing file %s\n", idl_files[i]);
+    rinfo.input_filename = idl_files[i];
+    if (!forb_idl_to_backend(idl_files[i], &rinfo)) {
+      g_warning("%s compilation failed", idl_files[i]);
+      retval = 1;
+    }
+  }
+
+  exit (retval);
+}
diff --git a/src/forb/forb-idl/forb-idl-utils.c b/src/forb/forb-idl/forb-idl-utils.c
new file mode 100644 (file)
index 0000000..759aff2
--- /dev/null
@@ -0,0 +1,718 @@
+#include "config.h"
+#include "forb-idl2.h"
+#include <string.h>
+#include <inttypes.h>
+
+void
+forb_idl_check_oneway_op (IDL_tree op)
+{
+       g_assert (IDL_NODE_TYPE(op) == IDLN_OP_DCL);
+
+       if (IDL_OP_DCL (op).f_oneway) {
+               IDL_tree sub;
+
+               for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+                       IDL_tree param = IDL_LIST (sub).data;
+
+                       if (IDL_PARAM_DCL (param).attr == IDL_PARAM_OUT ||
+                           IDL_PARAM_DCL (param).attr == IDL_PARAM_INOUT) {
+                               g_warning ("Out or Inout parameter in declaration of oneway '%s'",
+                                          IDL_IDENT(IDL_OP_DCL(op).ident).str);
+                               break;
+                       }
+               }
+
+               if (IDL_OP_DCL (op).op_type_spec)
+                       g_warning ("Return value in declaration of oneway '%s'",
+                                  IDL_IDENT(IDL_OP_DCL(op).ident).str);
+       }
+}
+
+void
+forb_idl_attr_fake_ops(IDL_tree attr, IDL_ns ns)
+{
+  IDL_tree attr_name, ident, curnode, op1, op2, intf;
+  GString *attrname;
+  OIDL_Attr_Info *setme;
+
+  g_assert(attr && IDL_NODE_TYPE(attr) == IDLN_ATTR_DCL);
+
+  attrname = g_string_new(NULL);
+
+  for(curnode = IDL_ATTR_DCL(attr).simple_declarations; curnode; curnode = IDL_LIST(curnode).next) {
+    op1 = op2 = NULL;
+
+    attr_name = IDL_LIST(curnode).data;
+
+    g_string_printf(attrname, "_get_%s",
+                    IDL_IDENT(attr_name).str);
+    ident = IDL_ident_new(g_strdup(attrname->str));
+    IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name);
+    op1 = IDL_op_dcl_new(0, IDL_ATTR_DCL(attr).param_type_spec, ident, NULL, NULL, NULL);
+    IDL_NODE_UP(op1) = IDL_NODE_UP(attr);
+    intf = IDL_NODE_UP (IDL_NODE_UP (op1));
+    IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident);
+    IDL_ns_place_new(ns, ident);
+
+    if(!IDL_ATTR_DCL(attr).f_readonly) {
+      g_string_printf(attrname, "_set_%s",
+                      IDL_IDENT(attr_name).str);
+      ident = IDL_ident_new(g_strdup(attrname->str));
+      IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name);
+      op2 = IDL_op_dcl_new(0, NULL, ident, NULL, NULL, NULL);
+      IDL_NODE_UP(op2) = IDL_NODE_UP(attr);
+      intf = IDL_NODE_UP (IDL_NODE_UP (op2));
+      IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident);
+      IDL_ns_place_new(ns, ident);
+      IDL_OP_DCL(op2).parameter_dcls = IDL_list_new(
+                                                   IDL_param_dcl_new(IDL_PARAM_IN,
+                                                                     IDL_ATTR_DCL(attr).param_type_spec,
+                                                                     IDL_ident_new(g_strdup("value"))));
+    }
+
+    setme = g_new0(OIDL_Attr_Info, 1);
+    setme->op1 = op1;
+    setme->op2 = op2;
+    attr_name->data = setme;
+  }
+
+  g_string_free(attrname, TRUE);
+}
+
+#define INDENT_INCREMENT_1 2
+#define INDENT_INCREMENT_2 4
+
+static void do_indent(int level) {
+  int i;
+  for(i = 0; i < level; i++) g_print(" ");
+}
+
+void
+forb_idl_print_node(IDL_tree node, int indent_level)
+{
+  IDL_tree curnode;
+  char *s;
+
+  do_indent(indent_level);
+
+  if(node == NULL) {
+    g_print("(null)\n");
+    return;
+  }
+
+  g_print("[%d] ", IDL_NODE_REFS(node));
+
+  switch(IDL_NODE_TYPE(node)) {
+
+  case IDLN_NONE:
+    g_print("NONE\n");
+    break;
+
+  case IDLN_LIST:
+    g_print("LIST:\n");
+    for(curnode = node; curnode;
+       curnode = IDL_LIST(curnode).next) {
+      forb_idl_print_node(IDL_LIST(curnode).data, indent_level + INDENT_INCREMENT_1);
+    }
+    break;
+
+  case IDLN_GENTREE:
+    break;
+
+  case IDLN_INTEGER:
+    g_print("INTEGER: %" PRId64 "\n", IDL_INTEGER(node).value);
+    break;
+
+  case IDLN_STRING:
+    g_print("STRING: %s\n", IDL_STRING(node).value);
+    break;
+
+  case IDLN_WIDE_STRING:
+    g_print("WIDE STRING: %ls\n", IDL_WIDE_STRING(node).value);
+    break;
+
+  case IDLN_CHAR:
+    g_print("CHAR: %s\n", IDL_CHAR(node).value);
+    break;
+
+  case IDLN_WIDE_CHAR:
+    g_print("WIDE CHAR: %ls\n", IDL_WIDE_CHAR(node).value);
+    break;
+
+  case IDLN_FIXED:
+    g_print("FIXED: %s\n", IDL_FIXED(node).value);
+    break;
+
+  case IDLN_FLOAT:
+    g_print("FLOAT: %f\n", IDL_FLOAT(node).value);
+    break;
+
+  case IDLN_BOOLEAN:
+    g_print("BOOLEAN: %s\n", (IDL_BOOLEAN(node).value)?"True":"False");
+    break;
+
+  case IDLN_IDENT:
+    s = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(node), "_", 0);
+    g_print("IDENT: %s NSQ: %s RID: \"%s\"\n",
+           IDL_IDENT(node).str, s,
+           IDL_IDENT_REPO_ID(node) ? IDL_IDENT_REPO_ID(node) : "");
+    g_free(s);
+    break;
+
+  case IDLN_TYPE_DCL:
+    g_print("TYPE DCL:\n");
+    forb_idl_print_node(IDL_TYPE_DCL(node).type_spec, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("decls:\n");
+    forb_idl_print_node(IDL_TYPE_DCL(node).dcls, indent_level + INDENT_INCREMENT_2);
+    break;
+
+  case IDLN_CONST_DCL:
+    g_print("CONST DCL:\n");
+    forb_idl_print_node(IDL_CONST_DCL(node).const_type, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("ident:\n");
+    forb_idl_print_node(IDL_CONST_DCL(node).ident, indent_level + INDENT_INCREMENT_2);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("const_exp:\n");
+    forb_idl_print_node(IDL_CONST_DCL(node).const_exp, indent_level + INDENT_INCREMENT_2);
+    break;
+
+  case IDLN_EXCEPT_DCL:
+    g_print("EXCEPT DCL:\n");
+    forb_idl_print_node(IDL_EXCEPT_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("members:\n");
+    forb_idl_print_node(IDL_EXCEPT_DCL(node).members, indent_level + INDENT_INCREMENT_2);
+    break;
+
+  case IDLN_ATTR_DCL:
+    g_print("ATTR_DCL (%s):\n", (IDL_ATTR_DCL(node).f_readonly)?"readonly":"rw");
+    forb_idl_print_node(IDL_ATTR_DCL(node).param_type_spec, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("simple_declarations:\n");
+    forb_idl_print_node(IDL_ATTR_DCL(node).simple_declarations, indent_level + INDENT_INCREMENT_2);
+    break;
+
+  case IDLN_OP_DCL:
+    g_print("OP DCL (%s):\n", (IDL_OP_DCL(node).f_oneway)?"oneway":"normal");
+    forb_idl_print_node(IDL_OP_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("op_type_spec:\n");
+    forb_idl_print_node(IDL_OP_DCL(node).op_type_spec, indent_level + INDENT_INCREMENT_2);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("parameter_dcls:\n");
+    forb_idl_print_node(IDL_OP_DCL(node).parameter_dcls, indent_level + INDENT_INCREMENT_2);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("raises_expr:\n");
+    forb_idl_print_node(IDL_OP_DCL(node).raises_expr, indent_level + INDENT_INCREMENT_2);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("context_expr:\n");
+    forb_idl_print_node(IDL_OP_DCL(node).context_expr, indent_level + INDENT_INCREMENT_2);
+    break;
+
+  case IDLN_PARAM_DCL:
+    g_print("PARAM DCL: ");
+    switch(IDL_PARAM_DCL(node).attr) {
+    case IDL_PARAM_IN: g_print("(in)\n"); break;
+    case IDL_PARAM_OUT: g_print("(out)\n"); break;
+    case IDL_PARAM_INOUT: g_print("(inout)\n"); break;
+    }
+    forb_idl_print_node(IDL_PARAM_DCL(node).param_type_spec, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("simple_declarator:\n");
+    forb_idl_print_node(IDL_PARAM_DCL(node).simple_declarator, indent_level + INDENT_INCREMENT_2);
+    break;
+  case IDLN_FORWARD_DCL:
+    g_print("FORWARD DCL:\n");
+    forb_idl_print_node(IDL_FORWARD_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
+    break;
+  case IDLN_INTERFACE:
+    g_print("INTERFACE:\n");
+    forb_idl_print_node(IDL_INTERFACE(node).ident, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("inheritance_spec:\n");
+    forb_idl_print_node(IDL_INTERFACE(node).inheritance_spec, indent_level + INDENT_INCREMENT_2);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("body:\n");
+    forb_idl_print_node(IDL_INTERFACE(node).body, indent_level + INDENT_INCREMENT_2);
+    break;
+  case IDLN_MODULE:
+    g_print("MODULE:\n");
+    forb_idl_print_node(IDL_MODULE(node).ident, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("definition_list:\n");
+    forb_idl_print_node(IDL_MODULE(node).definition_list, indent_level + INDENT_INCREMENT_2);
+    break;
+
+  case IDLN_TYPE_INTEGER:
+    if(!IDL_TYPE_INTEGER(node).f_signed) g_print("TYPE unsigned ");
+    switch(IDL_TYPE_INTEGER(node).f_type) {
+    case IDL_INTEGER_TYPE_SHORT: g_print("short\n"); break;
+    case IDL_INTEGER_TYPE_LONG: g_print("long\n"); break;
+    case IDL_INTEGER_TYPE_LONGLONG: g_print("long long\n"); break;
+    }
+    break;
+  case IDLN_TYPE_FLOAT:
+    switch(IDL_TYPE_FLOAT(node).f_type) {
+    case IDL_FLOAT_TYPE_FLOAT: g_print("TYPE float\n"); break;
+    case IDL_FLOAT_TYPE_DOUBLE: g_print("TYPE double\n"); break;
+    case IDL_FLOAT_TYPE_LONGDOUBLE: g_print("TYPE long double\n"); break;
+    }
+    break;
+  case IDLN_TYPE_FIXED:
+    g_print("TYPE fixed:\n");
+    forb_idl_print_node(IDL_TYPE_FIXED(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
+    forb_idl_print_node(IDL_TYPE_FIXED(node).integer_lit, indent_level + INDENT_INCREMENT_1);
+    break;
+  case IDLN_TYPE_STRING:
+    g_print("TYPE string:\n");
+    forb_idl_print_node(IDL_TYPE_STRING(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
+    break;
+  case IDLN_TYPE_WIDE_STRING:
+    g_print("TYPE wide string:\n");
+    forb_idl_print_node(IDL_TYPE_WIDE_STRING(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
+    break;
+  case IDLN_TYPE_ENUM:
+    g_print("TYPE enum:\n");
+    forb_idl_print_node(IDL_TYPE_ENUM(node).ident, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("enumerator_list:\n");
+    forb_idl_print_node(IDL_TYPE_ENUM(node).enumerator_list, indent_level + INDENT_INCREMENT_2);
+    break;
+  case IDLN_TYPE_ARRAY:
+    g_print("TYPE array:\n");
+    forb_idl_print_node(IDL_TYPE_ARRAY(node).ident, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("size_list:\n");
+    forb_idl_print_node(IDL_TYPE_ARRAY(node).size_list, indent_level + INDENT_INCREMENT_2);
+    break;
+  case IDLN_TYPE_SEQUENCE:
+    g_print("TYPE sequence:\n");
+    forb_idl_print_node(IDL_TYPE_SEQUENCE(node).simple_type_spec, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("positive_int_const:\n");
+    forb_idl_print_node(IDL_TYPE_SEQUENCE(node).positive_int_const, indent_level + INDENT_INCREMENT_2);
+    break;
+  case IDLN_TYPE_STRUCT:
+    g_print("TYPE struct:\n");
+    forb_idl_print_node(IDL_TYPE_STRUCT(node).ident, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("member_list:\n");
+    forb_idl_print_node(IDL_TYPE_STRUCT(node).member_list, indent_level + INDENT_INCREMENT_2);
+    break;
+  case IDLN_TYPE_UNION:
+    g_print("TYPE union:\n");
+    forb_idl_print_node(IDL_TYPE_UNION(node).ident, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("switch_type_spec:\n");
+    forb_idl_print_node(IDL_TYPE_UNION(node).switch_type_spec, indent_level + INDENT_INCREMENT_2);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("switch_body:\n");
+    forb_idl_print_node(IDL_TYPE_UNION(node).switch_body, indent_level + INDENT_INCREMENT_2);
+    break;
+  case IDLN_MEMBER:
+    g_print("MEMBER:\n");
+    forb_idl_print_node(IDL_MEMBER(node).type_spec, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("dcls:\n");
+    forb_idl_print_node(IDL_MEMBER(node).dcls, indent_level + INDENT_INCREMENT_2);
+    break;
+  case IDLN_CASE_STMT:
+    g_print("CASE_STMT:\n");
+    forb_idl_print_node(IDL_CASE_STMT(node).labels, indent_level + INDENT_INCREMENT_1);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("element_spec:\n");
+    forb_idl_print_node(IDL_CASE_STMT(node).element_spec, indent_level + INDENT_INCREMENT_2);
+    break;
+  case IDLN_BINOP:
+    g_print("BINOP ");
+    switch(IDL_BINOP(node).op) {
+    case IDL_BINOP_OR: g_print("or:\n"); break;
+    case IDL_BINOP_XOR: g_print("xor:\n"); break;
+    case IDL_BINOP_AND: g_print("and:\n"); break;
+    case IDL_BINOP_SHR: g_print("shr:\n"); break;
+    case IDL_BINOP_SHL: g_print("shl:\n"); break;
+    case IDL_BINOP_ADD: g_print("add:\n"); break;
+    case IDL_BINOP_SUB: g_print("sub:\n"); break;
+    case IDL_BINOP_MULT: g_print("mult:\n"); break;
+    case IDL_BINOP_DIV: g_print("div:\n"); break;
+    case IDL_BINOP_MOD: g_print("mod:\n"); break;
+    }
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("left:\n");
+    forb_idl_print_node(IDL_BINOP(node).left, indent_level + INDENT_INCREMENT_2);
+    do_indent(indent_level + INDENT_INCREMENT_1); g_print("right:\n");
+    forb_idl_print_node(IDL_BINOP(node).right, indent_level + INDENT_INCREMENT_2);
+    break;
+  case IDLN_UNARYOP:
+    g_print("UNARYOP ");
+    switch(IDL_UNARYOP(node).op) {
+    case IDL_UNARYOP_PLUS: g_print("plus:\n"); break;
+    case IDL_UNARYOP_MINUS: g_print("minus:\n"); break;
+    case IDL_UNARYOP_COMPLEMENT: g_print("complement:\n"); break;
+    }
+    forb_idl_print_node(IDL_UNARYOP(node).operand, indent_level + INDENT_INCREMENT_1);
+    break;
+  case IDLN_TYPE_CHAR:
+    g_print("TYPE char\n");
+    break;
+  case IDLN_TYPE_WIDE_CHAR:
+    g_print("TYPE wide char\n");
+    break;
+  case IDLN_TYPE_BOOLEAN:
+    g_print("TYPE boolean\n");
+    break;
+  case IDLN_TYPE_OCTET:
+    g_print("TYPE octet\n");
+    break;
+  case IDLN_TYPE_OBJECT:
+    g_print("TYPE object\n");
+    break;
+  case IDLN_TYPE_ANY:
+    g_print("TYPE any\n");
+    break;
+  case IDLN_TYPE_TYPECODE:
+    g_print("TYPE TypeCode\n");
+    break;
+  case IDLN_CODEFRAG:
+    g_print("CODEFRAG\n");
+    break;
+  case IDLN_SRCFILE:
+    g_print("SRCFILE %s\n", IDL_SRCFILE(node).filename);
+    break;
+  default:
+    g_print("unhandled %d\n", IDL_NODE_TYPE(node));
+  }
+}
+
+static void
+IDL_tree_traverse_helper(IDL_tree p, GFunc f,
+                        gconstpointer func_data,
+                        GHashTable *visited_nodes,
+                        gboolean    include_self)
+{
+       IDL_tree curitem;
+
+       if (g_hash_table_lookup (visited_nodes, p))
+               return;
+
+       g_hash_table_insert (visited_nodes, p, ((gpointer)1));
+
+       for (curitem = IDL_INTERFACE (p).inheritance_spec; curitem;
+            curitem = IDL_LIST (curitem).next) {
+               IDL_tree_traverse_helper (IDL_get_parent_node 
+                       (IDL_LIST (curitem).data, IDLN_INTERFACE, NULL), f, func_data, visited_nodes, TRUE);
+       }
+
+       if (include_self)
+               f(p, (gpointer)func_data);
+}
+
+void
+IDL_tree_traverse_parents_full (IDL_tree      p,
+                               GFunc         f,
+                               gconstpointer func_data,
+                               gboolean      include_self)
+{
+       GHashTable *visited_nodes = g_hash_table_new (NULL, g_direct_equal);
+
+       if (!(p && f))
+               return;
+
+       if (IDL_NODE_TYPE(p) != IDLN_INTERFACE)
+               p = IDL_get_parent_node (p, IDLN_INTERFACE, NULL);
+
+       if (!p)
+               return;
+
+       IDL_tree_traverse_helper (p, f, func_data, visited_nodes, include_self);
+
+       g_hash_table_destroy (visited_nodes);
+}
+
+void
+IDL_tree_traverse_parents (IDL_tree p,
+                          GFunc f,
+                          gconstpointer func_data)
+{
+       IDL_tree_traverse_parents_full (p, f, func_data, TRUE);
+}
+
+/* For use by below function */
+static const int *
+forb_cbe_get_typeoffsets_table (void)
+{
+  static int typeoffsets[IDLN_LAST];
+  static gboolean initialized = FALSE;
+  
+  if (!initialized) {
+    int i;
+
+    for (i = 0; i < IDLN_LAST; ++i)
+      typeoffsets[i] = -1;
+
+    typeoffsets[IDLN_FORWARD_DCL] = 8; /* (same as objref) */
+    typeoffsets[IDLN_TYPE_INTEGER] = 0;
+    typeoffsets[IDLN_TYPE_FLOAT] = 0;
+    typeoffsets[IDLN_TYPE_FIXED] = 3;
+    typeoffsets[IDLN_TYPE_CHAR] = 5;
+    typeoffsets[IDLN_TYPE_WIDE_CHAR] = 6;
+    typeoffsets[IDLN_TYPE_STRING] = 12;
+    typeoffsets[IDLN_TYPE_WIDE_STRING] = 13;
+    typeoffsets[IDLN_TYPE_BOOLEAN] = 4;
+    typeoffsets[IDLN_TYPE_OCTET] = 7;
+    typeoffsets[IDLN_TYPE_ANY] = 16;
+    typeoffsets[IDLN_TYPE_OBJECT] = 9;
+    typeoffsets[IDLN_TYPE_TYPECODE] = 9;
+    typeoffsets[IDLN_TYPE_ENUM] = 8;
+    typeoffsets[IDLN_TYPE_SEQUENCE] = 14;
+    typeoffsets[IDLN_TYPE_ARRAY] = 15;
+    typeoffsets[IDLN_TYPE_STRUCT] = 10;
+    typeoffsets[IDLN_TYPE_UNION] = 11;
+    typeoffsets[IDLN_NATIVE] = 15; /* no pointers ever, same as fixed array */
+    typeoffsets[IDLN_INTERFACE] = 9; /* (same as objref) */
+    
+    initialized = TRUE;
+  }
+  
+  return typeoffsets;
+}
+
+
+/**
+       This is a rather hairy function. Its purpose is to output the
+       required number of *'s that indicate the amount of indirection
+       for input, output, & input-output parameters, and return
+       values.  We do this by having a table of the number of *'s for
+       each type and purpose (nptrrefs_required), taken from 19.20
+       of the CORBA 2.2 spec, and then having a table that translates
+       from the IDLN_* enums into an index into nptrrefs_required (typeoffsets)
+**/
+gint
+oidl_param_info(IDL_tree in_param, IDL_ParamRole role, gboolean *isSlice)
+{
+       IDL_tree param;
+       const int * const typeoffsets = forb_cbe_get_typeoffsets_table ();
+       const int nptrrefs_required[][4] = {
+               {0,1,1,0} /* float */,
+               {0,1,1,0} /* double */,
+               {0,1,1,0} /* long double */,
+               {1,1,1,0} /* fixed_d_s 3 */, 
+               {0,1,1,0} /* boolean */,
+               {0,1,1,0} /* char */,
+               {0,1,1,0} /* wchar */,
+               {0,1,1,0} /* octet */,
+               {0,1,1,0} /* enum */,
+               {0,1,1,0} /* objref */,
+               {1,1,1,0} /* fixed struct 10 */,
+               {1,1,1,0} /* fixed union */,
+               {0,1,1,0} /* string */,
+               {0,1,1,0} /* wstring */,
+               {1,1,2,1} /* sequence */,
+               {0,0,0,0} /* fixed array */,
+               {1,1,2,1} /* any 16 */
+       };
+       int retval = 0;
+       int typeidx;
+
+       *isSlice = FALSE;
+
+       if(!in_param)
+               return 0; /* void */
+
+       /* Now, how do we use this table? :) */
+       param = forb_cbe_get_typespec (in_param);
+
+       g_assert (param);
+
+       switch (IDL_NODE_TYPE (param)) {
+       case IDLN_TYPE_STRUCT:
+       case IDLN_TYPE_UNION:
+               if (((role == DATA_RETURN) || (role == DATA_OUT)) &&
+                   !forb_cbe_type_is_fixed_length(param))
+                       retval++;
+               break;
+
+       case IDLN_TYPE_ARRAY:
+               if ( role == DATA_RETURN ) {
+                       *isSlice = TRUE;
+                       retval = 1;
+
+               } else if (role == DATA_OUT &&
+                          !forb_cbe_type_is_fixed_length (param)) {
+                       *isSlice = TRUE;
+                       retval = 2;
+               }
+               break;
+
+       case IDLN_NATIVE:
+               if ( IDL_NATIVE (param).user_type
+                    && strcmp (IDL_NATIVE (param).user_type,
+                               "IDL_variable_length_struct") == 0 ) {
+                       return role == DATA_OUT ? 2 : 1;
+               }
+               else {
+                       return role == DATA_IN ? 0 : 1;
+                 
+               }
+               break;
+
+       case IDLN_EXCEPT_DCL:
+               fprintf (stderr, "Error: exception declared at '%s:%d' cannot be "
+                        "used as a method parameter\n", in_param->_file,
+                        in_param->_line);
+               exit (1);
+               break;
+       default:
+               break;
+       }
+
+       /* ERROR ! */
+       typeidx = typeoffsets [IDL_NODE_TYPE (param)];
+       g_assert (typeidx >= 0);
+
+       switch (role) {
+       case DATA_IN:
+               role = 0;
+               break;
+       case DATA_INOUT:
+               role = 1;
+               break;
+       case DATA_OUT:
+               role = 2;
+               break;
+       case DATA_RETURN:
+               role = 3;
+               break;
+       default:
+               g_assert_not_reached ();
+               break;
+       }
+
+       retval += nptrrefs_required [typeidx] [role];
+
+       return retval;
+}
+
+/**
+    Fixed-length-ness is a property that CORBA defines, and it is
+    a property of each type, not each kind.  Furthermore, it doesnt
+    depend on the language mapping. Generally, the GIOP coding
+    a fixed length variable will be a known length (determined by the TC),
+    regardless of the data within the variable.
+
+    With the C mapping, fixed --> nothing to free in this node
+    Note that in the C mapping, everything is a struct and is
+    fixed length in that sense. Thus variable length types show
+    up in C as pointers.
+
+    Recursive types introduced by sequences are not a problem for this
+    func, because sequences are not fixed length, and terminate
+    the recursion.
+**/
+gboolean
+forb_cbe_type_is_fixed_length(IDL_tree ts)
+{
+  gboolean is_fixed = TRUE;
+  IDL_tree curitem;
+
+  ts = forb_cbe_get_typespec(ts);
+  switch(IDL_NODE_TYPE(ts)) {
+  case IDLN_TYPE_FLOAT:
+  case IDLN_TYPE_INTEGER:
+  case IDLN_TYPE_ENUM:
+  case IDLN_TYPE_CHAR:
+  case IDLN_TYPE_WIDE_CHAR:
+  case IDLN_TYPE_OCTET:
+  case IDLN_TYPE_BOOLEAN:
+    return TRUE;
+    break;
+  case IDLN_TYPE_SEQUENCE:
+  case IDLN_TYPE_STRING:
+  case IDLN_TYPE_WIDE_STRING:
+  case IDLN_TYPE_OBJECT:
+  case IDLN_FORWARD_DCL:
+  case IDLN_INTERFACE:
+  case IDLN_TYPE_ANY:
+  case IDLN_NATIVE:
+  case IDLN_TYPE_TYPECODE:
+    return FALSE;
+    break;
+  case IDLN_TYPE_UNION:
+    for(curitem = IDL_TYPE_UNION(ts).switch_body; curitem;
+       curitem = IDL_LIST(curitem).next) {
+      is_fixed &= forb_cbe_type_is_fixed_length(IDL_LIST(IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec).data);
+    }
+    return is_fixed;
+    break;
+  case IDLN_EXCEPT_DCL:
+  case IDLN_TYPE_STRUCT:
+    for(curitem = IDL_TYPE_STRUCT(ts).member_list; curitem;
+       curitem = IDL_LIST(curitem).next) {
+      is_fixed &= forb_cbe_type_is_fixed_length(IDL_LIST(curitem).data);
+    }
+    return is_fixed;
+    break;
+  case IDLN_TYPE_ARRAY:
+    return forb_cbe_type_is_fixed_length(IDL_TYPE_DCL(IDL_get_parent_node(ts, IDLN_TYPE_DCL, NULL)).type_spec);
+    break;
+  case IDLN_TYPE_DCL:
+    return forb_cbe_type_is_fixed_length(IDL_TYPE_DCL(ts).type_spec);
+    break;
+  case IDLN_IDENT:
+  case IDLN_LIST:
+    return forb_cbe_type_is_fixed_length(IDL_NODE_UP(ts));
+    break;
+  case IDLN_MEMBER:
+    return forb_cbe_type_is_fixed_length(IDL_MEMBER(ts).type_spec);
+    break;
+  default:
+    g_warning("I'm not sure if type %s is fixed-length", IDL_tree_type_names[IDL_NODE_TYPE(ts)]);
+    return FALSE;
+  }
+}
+
+IDL_tree
+forb_cbe_get_typespec(IDL_tree node)
+{
+  if(node == NULL)
+    return NULL;
+
+  switch(IDL_NODE_TYPE(node)) {
+  case IDLN_TYPE_INTEGER:
+  case IDLN_TYPE_FLOAT:
+  case IDLN_TYPE_FIXED:
+  case IDLN_TYPE_CHAR:
+  case IDLN_TYPE_WIDE_CHAR:
+  case IDLN_TYPE_STRING:
+  case IDLN_TYPE_WIDE_STRING:
+  case IDLN_TYPE_BOOLEAN:
+  case IDLN_TYPE_OCTET:
+  case IDLN_TYPE_ANY:
+  case IDLN_TYPE_OBJECT:
+  case IDLN_TYPE_ENUM:
+  case IDLN_TYPE_SEQUENCE:
+  case IDLN_TYPE_ARRAY:
+  case IDLN_TYPE_STRUCT:
+  case IDLN_TYPE_UNION:
+  case IDLN_EXCEPT_DCL:
+  case IDLN_FORWARD_DCL:
+  case IDLN_INTERFACE:
+  case IDLN_NATIVE:
+  case IDLN_TYPE_TYPECODE:
+    return node;
+    break;
+  case IDLN_TYPE_DCL:
+    return forb_cbe_get_typespec(IDL_TYPE_DCL(node).type_spec);
+    break;
+  case IDLN_PARAM_DCL:
+    return forb_cbe_get_typespec(IDL_PARAM_DCL(node).param_type_spec);
+    break;
+  case IDLN_MEMBER:
+    return forb_cbe_get_typespec(IDL_MEMBER(node).type_spec);
+    break;
+  case IDLN_LIST:
+  case IDLN_IDENT:
+    return forb_cbe_get_typespec(IDL_get_parent_node(node, IDLN_ANY, NULL));
+    break;
+  default:
+    g_error("Unhandled node type %s!", IDL_tree_type_names[IDL_NODE_TYPE(node)]);
+    return NULL;
+  }
+}
+
+IDL_ParamRole
+oidl_attr_to_paramrole(enum IDL_param_attr attr)
+{
+  switch(attr) {
+  case IDL_PARAM_IN:
+    return DATA_IN;
+  case IDL_PARAM_OUT:
+    return DATA_OUT;
+  case IDL_PARAM_INOUT:
+    return DATA_INOUT;
+  default:
+    g_warning("Unknown IDL_param_attr %d", attr);
+    return -1;
+  }
+}
diff --git a/src/forb/forb-idl/forb-idl2.h b/src/forb/forb-idl/forb-idl2.h
new file mode 100644 (file)
index 0000000..d9b60c2
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef FORB_IDL2_H
+#define FORB_IDL2_H 1
+
+#include "forb-idl3-types.h"
+
+gboolean forb_idl_to_backend     (const char    *filename,
+                                  OIDL_Run_Info *rinfo);
+
+gboolean forb_idl_backend_output (OIDL_Run_Info *rinfo,
+                                  IDL_tree       tree);
+
+/* Utils */
+void     forb_idl_attr_fake_ops         (IDL_tree      attr,
+                                         IDL_ns        ns);
+void     forb_idl_print_node            (IDL_tree      node,
+                                         int           indent_level);
+void     IDL_tree_traverse_parents       (IDL_tree      p,
+                                         GFunc         f,
+                                         gconstpointer func_data);
+void     IDL_tree_traverse_parents_full  (IDL_tree      p,
+                                         GFunc         f,
+                                         gconstpointer func_data, 
+                                         gboolean      include_self);
+gboolean forb_cbe_type_contains_complex (IDL_tree      ts);
+void     forb_idl_check_oneway_op       (IDL_tree      op);
+
+typedef enum { DATA_IN=1, DATA_INOUT=2, DATA_OUT=4, DATA_RETURN=8 } IDL_ParamRole;
+gint oidl_param_info(IDL_tree param, IDL_ParamRole role, gboolean *isSlice);
+
+gboolean forb_cbe_type_is_fixed_length(IDL_tree ts);
+IDL_tree forb_cbe_get_typespec(IDL_tree node);
+IDL_ParamRole oidl_attr_to_paramrole(enum IDL_param_attr attr);
+
+#define FORB_RETVAL_VAR_NAME "_forb_retval"
+#define FORB_EPV_VAR_NAME    "_FORB_epv"
+
+#endif /* FORB_IDL2_H */
diff --git a/src/forb/forb-idl/forb-idl3-types.h b/src/forb/forb-idl/forb-idl3-types.h
new file mode 100644 (file)
index 0000000..984df0e
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef ORBIT_IDL3_TYPES_H
+#define ORBIT_IDL3_TYPES_H 1
+
+#include <errno.h>
+#include <stdio.h>
+#include <libIDL/IDL.h>
+/* #include <orbit/util/orbit-util.h> */
+/* #include <orbit/orbit-config.h> */
+
+typedef struct _OIDL_Marshal_Context OIDL_Marshal_Context;
+
+#define OUTPUT_NUM_PASSES 7
+
+typedef struct {
+  char *cpp_args;
+  int debug_level;
+  int idl_warn_level;
+  int show_cpp_errors;
+  int is_pidl;
+  int do_skel_defs;    /* gen defs within the header file */
+
+  enum { OUTPUT_STUBS=1<<0,
+        OUTPUT_SKELS=1<<1,
+        OUTPUT_COMMON=1<<2,
+        OUTPUT_HEADERS=1<<3,
+        OUTPUT_SKELIMPL=1<<4,
+        OUTPUT_IMODULE=1<<5,
+        OUTPUT_DEPS=1<<6 /* Make sure this is always the last pass or dep output will break. */
+  } enabled_passes;
+
+  char *output_language;
+  char *input_filename;
+  char *include;
+  char *backend_directory;
+  char *deps_file;
+  char *header_guard_prefix;
+  char *output_directory;
+  gboolean onlytop;
+  gboolean idata;
+
+  IDL_ns ns; /* Use ns instead of namespace because that's a C++ reserved keyword */
+} OIDL_Run_Info;
+
+typedef struct {
+  IDL_tree op1;
+  IDL_tree op2;
+} OIDL_Attr_Info;
+
+#endif
diff --git a/src/forb/forb-idl/forb_config.h b/src/forb/forb-idl/forb_config.h
new file mode 100644 (file)
index 0000000..a8834b5
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef FORB_CONFIG_H
+#define FORB_CONFIG_H
+
+/* #define WORDS_BIGENDIAN */
+#undef WORDS_BIGENDIAN
+
+#define FORB_CONFIG_SERIAL 0
+
+#endif
diff --git a/src/forb/src/Makefile b/src/forb/src/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/forb/src/Makefile.omk b/src/forb/src/Makefile.omk
new file mode 100644 (file)
index 0000000..8a382b8
--- /dev/null
@@ -0,0 +1,75 @@
+SUBDIRS = tests
+
+CFLAGS += -I.
+
+# IDL_COMPILER += --pidl
+
+shared_LIBRARIES += forb
+forb_SOURCES = forb.c cdr.c sha1.c uuid.c iop.c proto.c syncobj.c      \
+              request.c executor.c object.c peer.c port.c refcnt.c     \
+              exec_req.c regref.c discovery.c daemon.c
+forb_CLIENT_IDL = types.idl iop-idl.idl forb-idl.idl
+forb_SERVER_IDL = forb-idl.idl
+
+to_forb_subdir=$(1)->forb/$(strip $(1))
+
+ifeq ($(CONFIG_FORB_PROTO_UNIX),y)
+forb_SOURCES += proto_unix.c
+renamed_include_HEADERS += $(call to_forb_subdir, proto_unix.h) 
+endif
+
+# TODO: proto_inet should be a separate library as it should be used
+# only by FCB
+forb_SOURCES += proto_inet.c
+renamed_include_HEADERS += $(call to_forb_subdir, proto_inet.h) 
+
+
+include_HEADERS = forb.h
+renamed_include_HEADERS += \
+       $(call to_forb_subdir, basic_types.h) \
+       $(call to_forb_subdir, cdr.h) \
+       $(call to_forb_subdir, cdr_codec.h) \
+       $(call to_forb_subdir, executor.h) \
+       $(call to_forb_subdir, exec_req.h) \
+       $(call to_forb_subdir, forb-internal.h) \
+       $(call to_forb_subdir, iop.h) \
+       $(call to_forb_subdir, object.h) \
+       $(call to_forb_subdir, object_type.h) \
+       $(call to_forb_subdir, port.h) \
+       $(call to_forb_subdir, refcnt.h) \
+       $(call to_forb_subdir, request.h) \
+       $(call to_forb_subdir, syncobj.h) \
+       $(call to_forb_subdir, server_id.h) \
+       $(call to_forb_subdir, peer.h) \
+       $(call to_forb_subdir, uuid.h)
+
+renamed_include_GEN_HEADERS = \
+       $(call to_forb_subdir,forb-idl.h) \
+       $(call to_forb_subdir,iop-idl.h) \
+       $(call to_forb_subdir,types.h)
+
+default_CONFIG = CONFIG_FORB_PROTO_UNIX=y \
+                CONFIG_FORB_RECV_BUF_SIZE=4096 \
+                CONFIG_FORB_PROTO_INET_DEFAULT=n
+
+config_include_HEADERS = forb/config.h
+config_DEFINES = CONFIG_FORB_PROTO_UNIX \
+                CONFIG_FORB_RECV_BUF_SIZE \
+                CONFIG_FORB_PROTO_INET_DEFAULT \
+                CONFIG_FCB     # To see whether we are compiled with FRSH_FORB
+
+include-pass_HOOKS = log_domains.inc #request_gavl.inc
+
+log_domains.inc: $(addprefix $(SOURCES_DIR)/,ul_log_domains $(forb_SOURCES))
+       @echo "  UL_LOG  $@"
+       $(Q)$(SOURCES_DIR)/ul_log_domains --array forb_logreg_domains_array \
+               $(SOURCES_DIR) > $@
+
+clean-custom:
+       -$(Q)rm log_domains.inc
+
+# request_gavl.inc: $(SOURCES_DIR)/request_gavl.c
+#      @echo "  CPP     $@"
+#      $(Q)$(c_o_COMPILE) -o $@.tmp -E $<
+#      $(Q)tail -n 1 $@.tmp|indent > $@
+
diff --git a/src/forb/src/basic_types.h b/src/forb/src/basic_types.h
new file mode 100644 (file)
index 0000000..2985a4d
--- /dev/null
@@ -0,0 +1,153 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+#ifndef BASIC_TYPES_H
+#define BASIC_TYPES_H 1
+
+#include <stdint.h>
+#include <string.h>
+
+enum {
+       CORBA_FALSE = 0,
+       CORBA_TRUE  = 1
+};
+
+typedef int16_t   CORBA_short;
+typedef int32_t   CORBA_long;
+typedef int64_t   CORBA_long_long;
+typedef uint16_t  CORBA_unsigned_short;
+typedef uint32_t  CORBA_unsigned_long;
+typedef uint64_t  CORBA_unsigned_long_long;
+typedef float     CORBA_float;
+typedef double    CORBA_double;
+typedef char     CORBA_char;
+typedef int16_t   CORBA_wchar;
+typedef uint8_t   CORBA_boolean;
+typedef uint8_t   CORBA_octet;
+typedef double    CORBA_long_double;
+
+/*
+ * Bad hack, oh well
+ */
+
+typedef CORBA_char  *CORBA_string;
+typedef CORBA_wchar *CORBA_wstring;
+
+#define CORBA_sequence_get_release(seq) ((seq)->_release)
+/** 
+ * CORBA_sequence_set_release can be used to set the state of the release flag.
+ * 
+ * @param seq
+ * 
+ * @param val The value of the release flag.  If the flag is set to
+ * TRUE, the sequence effectively "owns" the storage pointed to by
+ * _buffer; if FALSE, the programmer is responsible for the storage
+ * [99-07-35.pdf].
+ */
+#define CORBA_sequence_set_release(seq, val) ((seq)->_release = (val))
+
+CORBA_boolean
+__forb_sequence_alloc_buf_internal(void *seq, size_t seq_size,
+                                  void **buf_pptr, CORBA_unsigned_long *maximum_ptr,
+                                  CORBA_unsigned_long num_elements, size_t elem_size);
+
+/** @name Sequence helper macros */
+/**@{*/
+/**
+ *
+ *
+ * @param seq
+ * @param num_elements
+ *
+ * @return CORBA_TRUE if the allocation was sucessfull, CORBA_FALSE if wasn't.
+ */
+#define forb_sequence_alloc_buf(seq, num_elements)                     \
+       __forb_sequence_alloc_buf_internal((seq), sizeof(*(seq)),       \
+                                          (void**)&(seq)->_buffer, &(seq)->_maximum, \
+                                          (num_elements), sizeof(*(seq)->_buffer))
+
+#define forb_sequence_alloc(seq, num_elements) do {            \
+               (seq) = forb_malloc(sizeof(*(seq)));            \
+               memset((seq), 0, sizeof(*(seq)));               \
+               forb_sequence_alloc_buf((seq), (num_elements)); \
+       } while(0)
+
+static inline void forb_no_destructor() {}
+
+#define forb_sequence_free_buf(seq, elem_destructor) do {              \
+               if (CORBA_sequence_get_release(seq)) {                  \
+                       CORBA_unsigned_long i;                          \
+                       for (i=0; i<(seq)->_length; i++) {              \
+                               elem_destructor(&(seq)->_buffer[i]);    \
+                       }                                               \
+                       forb_free((seq)->_buffer);                      \
+               }                                                       \
+       } while(0)
+
+#define forb_sequence_free(seq, elem_destructor) do {                  \
+               forb_sequence_free_buf((seq), (elem_destructor));       \
+               forb_free(seq);                                         \
+       } while(0)
+
+#define forb_sequence_elem(seq, index) ((seq)->_buffer[(index)])
+
+#define forb_sequence_length(seq) ((seq)->_length)
+#define forb_sequence_allocated(seq) ((seq)->_maximum)
+#define forb_sequence_ensure_allocated(seq, num)                       \
+       ((seq)->_buffer =                                               \
+        (forb_sequence_allocated(seq) < (num)) ?                       \
+               (forb_sequence_allocated(seq) = (num),                  \
+                realloc((seq)->_buffer, (num)*sizeof(*(seq)->_buffer))) : \
+        (seq)->_buffer)
+
+#define forb_sequence_foreach(seq, elemptr)          \
+       for ((elemptr)=&forb_sequence_elem((seq), 0); \
+            (elemptr)<&forb_sequence_elem((seq), forb_sequence_length(seq)); \
+            (elemptr)++)
+
+/**@}*/
+
+#endif
diff --git a/src/forb/src/cdr.c b/src/forb/src/cdr.c
new file mode 100644 (file)
index 0000000..2012b8e
--- /dev/null
@@ -0,0 +1,508 @@
+/*
+ *  $Id: cdr.c,v 0.0.0.1                2004/11/26
+ *
+ *                      CDR codeing
+ *
+ *  -------------------------------------------------------------------  
+ *                                ORTE                                 
+ *                      Open Real-Time Ethernet                       
+ *                                                                    
+ *                      Copyright (C) 2001-2006                       
+ *  Department of Control Engineering FEE CTU Prague, Czech Republic  
+ *                      http://dce.felk.cvut.cz                       
+ *                      http://www.ocera.org                          
+ *                                                                    
+ *  Author:             Petr Smolik    petr.smolik@wo.cz             
+ *  Advisor:            Pavel Pisa                                   
+ *  Project Responsible: Zdenek Hanzalek
+ *  
+ *  Modified for FORB by Michal Sojka <sojkam1@fel.cvut.cz>, 2008
+ *  --------------------------------------------------------------------
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  Original of source was from ORBit: A CORBA v2.2 ORB
+ *
+ */
+
+#include <forb/cdr.h>
+#include "forb.h"
+#include "forb_endian.h"
+#include <string.h>
+
+#define ALIGN_ADDRESS(this, boundary) \
+  ((void*)((( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))))
+
+#define FORB_CDR_GROW_AMOUNT 128
+
+CORBA_boolean 
+FORB_CDR_buffer_init(FORB_CDR_Codec *codec, const unsigned int size, const unsigned int first)
+{
+
+       if(codec->release_buffer) {
+               forb_free(codec->buffer);
+       }
+
+       if (first > size) {
+               return CORBA_FALSE;
+       }
+       codec->buffer=(CORBA_octet *)forb_malloc(size);
+       if (!codec->buffer) {
+               return CORBA_FALSE;
+       }
+       codec->buf_len=size;
+        codec->wptr_max=size;
+       FORB_CDR_buffer_reset(codec, first);
+        codec->release_buffer=CORBA_TRUE;
+
+       return CORBA_TRUE;
+}
+
+CORBA_boolean 
+FORB_CDR_buffer_reset(FORB_CDR_Codec *codec, const unsigned int first)
+{
+       if (first > codec->buf_len) {
+               return CORBA_FALSE;
+       }
+       codec->rptr = codec->wptr = codec->wptr_last = first;
+       return CORBA_TRUE;
+}
+
+CORBA_boolean 
+FORB_CDR_buffer_prepend(FORB_CDR_Codec *codec, const unsigned int len)
+{
+       if (codec->rptr < len) {
+               return CORBA_FALSE;
+       }
+       codec->rptr -= len;
+
+       codec->wptr = codec->rptr;
+
+       return CORBA_TRUE;
+}
+
+/*
+CORBA_boolean 
+FORB_CDR_buffer_grow(FORB_CDR_Codec *codec, const unsigned int growth)
+{
+       unsigned int real_growth,quot;
+
+       if(codec->release_buffer) {
+                quot = growth / FORB_CDR_GROW_AMOUNT;
+               real_growth=FORB_CDR_GROW_AMOUNT * (quot+1);
+               
+               codec->buffer=(CORBA_octet *)REALLOC(codec->buffer,
+                                                    codec->buf_len
+                                                    +real_growth);
+       }
+
+       return CORBA_TRUE;
+}
+*/
+CORBA_boolean 
+FORB_CDR_buffer_puts(FORB_CDR_Codec *codec, const void *data, const unsigned int len)
+{
+       if(codec->wptr+len > codec->wptr_max) {
+               return CORBA_FALSE; 
+       }
+
+       memcpy(&codec->buffer[codec->wptr], data, len);
+       codec->wptr+=len;
+       if (codec->wptr > codec->wptr_last) codec->wptr_last = codec->wptr;
+
+       return CORBA_TRUE;
+}
+
+CORBA_boolean 
+FORB_CDR_buffer_gets(FORB_CDR_Codec *codec, void *dest, const unsigned int len)
+{
+       if(codec->rptr+len > codec->buf_len) {
+               return CORBA_FALSE; 
+       }
+
+       memcpy(dest, &codec->buffer[codec->rptr], len);
+       codec->rptr+=len;
+
+       return CORBA_TRUE;
+}
+
+CORBA_boolean 
+FORB_CDR_buffer_put(FORB_CDR_Codec *codec, void *datum)
+{
+       if(codec->wptr+1 > codec->wptr_max) {
+               return(CORBA_FALSE);
+       }
+
+       codec->buffer[codec->wptr++]=*(unsigned char *)datum;
+       if (codec->wptr > codec->wptr_last) codec->wptr_last = codec->wptr;
+       return CORBA_TRUE;
+}
+
+CORBA_boolean 
+FORB_CDR_buffer_get(FORB_CDR_Codec *codec, void *dest)
+{
+       if(codec->rptr+1 > codec->buf_len) {
+               return(CORBA_FALSE);
+       }
+
+       *(CORBA_octet *)dest=codec->buffer[codec->rptr++];
+       return CORBA_TRUE;
+}
+
+#define FORB_CDR_buffer_put2(codec, datum) FORB_CDR_buffer_putn(codec, datum, 2)
+#define FORB_CDR_buffer_put4(codec, datum) FORB_CDR_buffer_putn(codec, datum, 4)
+#define FORB_CDR_buffer_put8(codec, datum) FORB_CDR_buffer_putn(codec, datum, 8)
+#define FORB_CDR_buffer_put16(codec, datum) FORB_CDR_buffer_putn(codec, datum, 16)
+#define FORB_CDR_buffer_get2(codec, dest) FORB_CDR_buffer_getn(codec, dest, 2)
+#define FORB_CDR_buffer_get4(codec, dest) FORB_CDR_buffer_getn(codec, dest, 4)
+#define FORB_CDR_buffer_get8(codec, dest) FORB_CDR_buffer_getn(codec, dest, 8)
+#define FORB_CDR_buffer_get16(codec, dest) FORB_CDR_buffer_getn(codec, dest, 16)
+
+static CORBA_boolean
+FORB_CDR_buffer_getn(FORB_CDR_Codec *codec, void *dest, int bsize)
+{
+       codec->rptr = (unsigned long)ALIGN_ADDRESS(codec->rptr, bsize);
+       if(codec->host_endian==codec->data_endian)
+               memcpy(dest, codec->buffer + codec->rptr, bsize);
+       else
+               forb_byteswap(dest, codec->buffer + codec->rptr, bsize);
+       codec->rptr += bsize;
+
+       return CORBA_TRUE;
+}
+
+static CORBA_boolean
+FORB_CDR_buffer_putn(FORB_CDR_Codec *codec, void *datum, int bsize)
+{
+        unsigned long forward,i;
+       
+       forward = (unsigned long)ALIGN_ADDRESS(codec->wptr, bsize);
+       if (forward+bsize > codec->wptr_max) {
+               return CORBA_FALSE;
+       }       
+
+       i = codec->wptr;
+        while(forward > i)
+               codec->buffer[i++] = '\0';
+
+       codec->wptr = forward;
+       if(codec->host_endian==codec->data_endian)
+               memcpy(codec->buffer + codec->wptr, datum, bsize);
+       else
+               forb_byteswap(codec->buffer + codec->wptr, datum, bsize);
+       codec->wptr += bsize;
+       if (codec->wptr > codec->wptr_last) codec->wptr_last = codec->wptr;
+
+       return CORBA_TRUE;
+}
+
+CORBA_boolean FORB_CDR_put_align(FORB_CDR_Codec *codec, unsigned bsize)
+{
+        unsigned long forward,i;
+       
+       forward = (unsigned long)ALIGN_ADDRESS(codec->wptr, bsize);
+       if (forward+bsize > codec->wptr_max) {
+               return CORBA_FALSE;
+       }       
+
+       i = codec->wptr;
+        while(forward > i)
+               codec->buffer[i++] = '\0';
+
+       codec->wptr = forward;
+       if (codec->wptr > codec->wptr_last) codec->wptr_last = codec->wptr;
+       return CORBA_TRUE;
+}
+
+CORBA_boolean FORB_CDR_get_align(FORB_CDR_Codec *codec, unsigned bsize)
+{
+       codec->rptr = (unsigned long)ALIGN_ADDRESS(codec->rptr, bsize);
+       return codec->rptr <= codec->wptr_max;
+}
+
+#define FORB_CDR_swap2(d,s) forb_byteswap((d), (s), 2)
+#define FORB_CDR_swap4(d,s) forb_byteswap((d), (s), 4)
+#define FORB_CDR_swap8(d,s) forb_byteswap((d), (s), 8)
+#define FORB_CDR_swap16(d,s) forb_byteswap((d), (s), 16)
+
+inline CORBA_boolean 
+FORB_CDR_put_short(FORB_CDR_Codec *codec, CORBA_short s)
+{
+       return FORB_CDR_buffer_put2(codec, &s);
+}
+
+inline CORBA_boolean 
+FORB_CDR_get_short(FORB_CDR_Codec *codec, CORBA_short *s)
+{
+       return FORB_CDR_buffer_get2(codec, s);
+}
+
+inline CORBA_boolean 
+FORB_CDR_put_ushort(FORB_CDR_Codec *codec, CORBA_unsigned_short us)
+{
+       return FORB_CDR_buffer_put2(codec, &us);
+}
+
+inline CORBA_boolean 
+FORB_CDR_get_ushort(FORB_CDR_Codec *codec, CORBA_unsigned_short *us)
+{
+       return FORB_CDR_buffer_get2(codec, us);
+}
+
+inline CORBA_boolean 
+FORB_CDR_put_long(FORB_CDR_Codec *codec, CORBA_long l)
+{
+       return FORB_CDR_buffer_put4(codec, &l);
+}
+
+inline CORBA_boolean 
+FORB_CDR_get_long(FORB_CDR_Codec *codec, CORBA_long *l)
+{
+       return FORB_CDR_buffer_get4(codec, l);
+}
+
+inline CORBA_boolean 
+FORB_CDR_put_ulong(FORB_CDR_Codec *codec, CORBA_unsigned_long ul)
+{
+       return FORB_CDR_buffer_put4(codec, &ul);
+}
+
+inline CORBA_boolean 
+FORB_CDR_get_ulong(FORB_CDR_Codec *codec, CORBA_unsigned_long *ul)
+{
+       return FORB_CDR_buffer_get4(codec, ul);
+}
+
+//#ifdef HAVE_CORBA_LONG_LONG
+inline CORBA_boolean 
+FORB_CDR_get_long_long(FORB_CDR_Codec *codec, CORBA_long_long *ul)
+{
+       return FORB_CDR_buffer_get8(codec, ul);
+}
+
+inline CORBA_boolean 
+FORB_CDR_put_long_long(FORB_CDR_Codec *codec, CORBA_long_long ll)
+{
+       return FORB_CDR_buffer_put8(codec, &ll);
+}
+
+inline CORBA_boolean 
+FORB_CDR_put_ulong_long(FORB_CDR_Codec *codec, CORBA_unsigned_long_long ll)
+{
+       return FORB_CDR_buffer_put8(codec, &ll);
+}
+
+inline CORBA_boolean 
+FORB_CDR_get_ulong_long(FORB_CDR_Codec *codec, CORBA_unsigned_long_long *ull)
+{
+       return FORB_CDR_buffer_get8(codec, ull);
+}
+//#endif /* HAVE_CORBA_LONG_LONG */
+
+inline CORBA_boolean 
+FORB_CDR_put_float(FORB_CDR_Codec *codec, CORBA_float f)
+{
+       return FORB_CDR_buffer_put4(codec, &f);
+}
+
+inline CORBA_boolean 
+FORB_CDR_get_float(FORB_CDR_Codec *codec, CORBA_float *f)
+{
+       return FORB_CDR_buffer_get4(codec, f);
+}
+
+inline CORBA_boolean 
+FORB_CDR_put_double(FORB_CDR_Codec *codec, CORBA_double d)
+{
+       return FORB_CDR_buffer_put8(codec, &d);
+}
+
+inline CORBA_boolean 
+FORB_CDR_get_double(FORB_CDR_Codec *codec, CORBA_double *d)
+{
+       return FORB_CDR_buffer_get8(codec, d);
+}
+
+inline CORBA_boolean 
+FORB_CDR_put_long_double(FORB_CDR_Codec *codec, CORBA_long_double ld)
+{
+       return FORB_CDR_buffer_put16(codec, &ld);
+}
+
+inline CORBA_boolean 
+FORB_CDR_put_octet(FORB_CDR_Codec *codec, CORBA_octet datum)
+{
+       return FORB_CDR_buffer_put(codec, &datum);
+}
+
+inline CORBA_boolean 
+FORB_CDR_get_octet(FORB_CDR_Codec *codec, CORBA_octet *datum)
+{
+       return(FORB_CDR_buffer_get(codec, datum));
+}
+
+inline CORBA_boolean 
+FORB_CDR_put_octets(FORB_CDR_Codec *codec, void *data, unsigned long len)
+{
+       return FORB_CDR_buffer_puts(codec, data, len);
+}
+
+inline CORBA_boolean 
+FORB_CDR_put_char(FORB_CDR_Codec *codec, CORBA_char c)
+{
+       return FORB_CDR_buffer_put(codec, &c);
+}
+
+inline CORBA_boolean 
+FORB_CDR_get_char(FORB_CDR_Codec *codec, CORBA_char *c)
+{
+       return FORB_CDR_buffer_get(codec, c);
+}
+
+inline CORBA_boolean 
+FORB_CDR_put_boolean(FORB_CDR_Codec *codec, CORBA_boolean datum)
+{
+       datum = datum&&1;
+       return FORB_CDR_buffer_put(codec, &datum);
+}
+
+inline CORBA_boolean 
+FORB_CDR_get_boolean(FORB_CDR_Codec *codec, CORBA_boolean *b)
+{
+       return FORB_CDR_buffer_get(codec, b);
+}
+
+CORBA_boolean 
+FORB_CDR_put_string(FORB_CDR_Codec *codec, const CORBA_char *str)
+{
+       unsigned int len;
+
+       if (str) 
+               len=strlen(str)+1;
+       else
+               len=0;
+
+       if (FORB_CDR_put_ulong(codec, len)==CORBA_FALSE) return -1;
+       return FORB_CDR_buffer_puts(codec, str, len);
+}
+
+CORBA_boolean 
+FORB_CDR_get_string_static(FORB_CDR_Codec *codec,CORBA_char **str)
+{
+       CORBA_unsigned_long len;
+
+       if(FORB_CDR_get_ulong(codec, (CORBA_unsigned_long *)&len)==CORBA_FALSE)
+               return CORBA_FALSE;
+
+       if((codec->rptr + len) > codec->buf_len)
+               return CORBA_FALSE;
+
+       *str = ((CORBA_char *)codec->buffer) + codec->rptr;
+
+       codec->rptr += len;
+
+       return CORBA_TRUE;
+}
+
+CORBA_boolean 
+FORB_CDR_get_string(FORB_CDR_Codec *codec, CORBA_char **str)
+{
+       CORBA_unsigned_long len;
+
+       if(FORB_CDR_get_ulong(codec, (CORBA_unsigned_long *)&len)==CORBA_FALSE)
+               return(CORBA_FALSE);
+
+       if(len==0)
+               return(CORBA_FALSE);
+
+       *str=forb_malloc(len);
+
+       if(FORB_CDR_buffer_gets(codec, *str, len)==CORBA_FALSE) {
+               forb_free(*str);
+               return(CORBA_FALSE);
+       }
+
+       if((*str)[len-1]!='\0') {
+               (*str)[len-1]='\0';
+       }
+
+       return(CORBA_TRUE);
+}
+
+CORBA_boolean 
+FORB_CDR_get_string_buff(FORB_CDR_Codec *codec, CORBA_char *str)
+{
+       CORBA_unsigned_long len;
+
+       if(FORB_CDR_get_ulong(codec, (CORBA_unsigned_long *)&len)==CORBA_FALSE)
+               return(CORBA_FALSE);
+
+       if(len==0)
+               return(CORBA_FALSE);
+
+       if(FORB_CDR_buffer_gets(codec, str, len)==CORBA_FALSE) {
+               return(CORBA_FALSE);
+       }
+
+       if(str[len-1]!='\0') {
+               str[len-1]='\0';
+       }
+
+       return(CORBA_TRUE);
+}
+
+CORBA_boolean 
+FORB_CDR_get_seq_begin(FORB_CDR_Codec *codec, CORBA_unsigned_long *ul)
+{
+       return(FORB_CDR_get_ulong(codec, (CORBA_unsigned_long *)ul));
+}
+
+FORB_CDR_Codec *
+FORB_CDR_codec_init_static(FORB_CDR_Codec *codec, forb_orb orb)
+{
+       memset(codec, 0, sizeof(FORB_CDR_Codec));
+
+       codec->host_endian = FLAG_ENDIANNESS;
+       codec->data_endian = FLAG_ENDIANNESS;
+       codec->orb = orb;
+
+       return codec;
+}
+
+FORB_CDR_Codec *
+FORB_CDR_codec_init(forb_orb orb)
+{
+       FORB_CDR_Codec *c;
+
+       c=forb_malloc(sizeof(FORB_CDR_Codec));
+       if (c) {
+               FORB_CDR_codec_init_static(c, orb);
+       }
+
+       return(c);
+}
+
+void 
+FORB_CDR_codec_release_buffer(FORB_CDR_Codec *codec)
+{
+       if(codec->release_buffer) {
+               forb_free(codec->buffer);
+               codec->release_buffer = CORBA_FALSE;
+       }
+}
+
+
+void 
+FORB_CDR_codec_free(FORB_CDR_Codec *codec)
+{
+       FORB_CDR_codec_release_buffer(codec);
+       forb_free(codec);
+}
diff --git a/src/forb/src/cdr.h b/src/forb/src/cdr.h
new file mode 100644 (file)
index 0000000..8eaa1d3
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ *  $Id: cdr.h,v 0.0.0.1                2004/11/26 
+ *
+ *  -------------------------------------------------------------------  
+ *                                ORTE                                 
+ *                      Open Real-Time Ethernet                       
+ *                                                                    
+ *                      Copyright (C) 2001-2006                       
+ *  Department of Control Engineering FEE CTU Prague, Czech Republic  
+ *                      http://dce.felk.cvut.cz                       
+ *                      http://www.ocera.org                          
+ *                                                                    
+ *  Author:             Petr Smolik    petr.smolik@wo.cz
+ *  Advisor:            Pavel Pisa                                   
+ *  Project Responsible: Zdenek Hanzalek
+ *  
+ *  Modified for FORB by Michal Sojka <sojkam1@fel.cvut.cz>, 2008
+ *  --------------------------------------------------------------------
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  Original of source was from ORBit: A CORBA v2.2 ORB
+ */
+/**
+ * @file   cdr.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:55:44 2008
+ * 
+ * @brief Handling of serialization/deserialization.
+ *
+ * Forked from ORTE project.
+ * 
+ * 
+ */
+#ifndef _FORB_CDR_H_
+#define _FORB_CDR_H_
+
+#include "basic_types.h"
+#include "cdr_codec.h"
+#include "object_type.h"
+
+/*
+ * Alignment of CORBA types mapped to C.
+ * These have *nothing* to do with CDR alignment.
+ */
+#define ORTE_ALIGNOF_CORBA_OCTET        1
+#define ORTE_ALIGNOF_CORBA_BOOLEAN      1
+#define ORTE_ALIGNOF_CORBA_CHAR         1
+#define ORTE_ALIGNOF_CORBA_WCHAR        2
+#define ORTE_ALIGNOF_CORBA_SHORT        2
+#define ORTE_ALIGNOF_CORBA_LONG         4
+#define ORTE_ALIGNOF_CORBA_LONG_LONG    8
+#define ORTE_ALIGNOF_CORBA_FLOAT        4
+#define ORTE_ALIGNOF_CORBA_DOUBLE       8
+#define ORTE_ALIGNOF_CORBA_LONG_DOUBLE  16
+#define ORTE_ALIGNOF_CORBA_STRUCT       1
+#define ORTE_ALIGNOF_CORBA_POINTER      4
+
+typedef enum {
+       BigEndian=0,
+       LittleEndian=1
+} FORB_CDR_Endianness;
+
+/**
+ * Codec used for serialization/deserialization
+ * 
+ * @host_endian: 
+ * @data_endian: 
+ * @buffer: buffer for data
+ * @buf_len: buffer length
+ * @wptr_max: maximal size of writing data 
+ * @wptr: write index
+ * @wptr_last: index of the data after the last written data
+ * @rptr: read index
+ * @readonly: readonly attribute 
+ * @release_buffer: use CORBA_TRUE if is necessary to free buffer memory after destruction of structure
+ * @orb: Needed for deserialization of object references.
+ *
+ * Struct @FORB_CDR_Codec is used by serialization and deserialization functions.
+ */
+struct FORB_CDR_Codec {
+       FORB_CDR_Endianness host_endian;
+       FORB_CDR_Endianness data_endian;
+       CORBA_octet *buffer;
+       unsigned int buf_len;
+       unsigned int wptr_max;
+       unsigned int wptr;
+       unsigned int wptr_last;
+       unsigned int rptr;
+       CORBA_boolean readonly;
+       CORBA_boolean release_buffer;
+       forb_orb orb;
+};
+
+#define HEXDIGIT(c) (isdigit((guchar)(c))?(c)-'0':tolower((guchar)(c))-'a'+10)
+#define HEXOCTET(a,b) ((HEXDIGIT((a)) << 4) | HEXDIGIT((b)))
+
+static inline CORBA_long FORB_CDR_data_size(FORB_CDR_Codec *codec)
+{
+       return codec->wptr_last - codec->rptr;
+}
+
+extern CORBA_boolean FORB_CDR_buffer_init(FORB_CDR_Codec *codec, const unsigned int size, const unsigned int first);
+extern CORBA_boolean FORB_CDR_buffer_reset(FORB_CDR_Codec *codec, const unsigned int first);
+extern CORBA_boolean FORB_CDR_buffer_prepend(FORB_CDR_Codec *codec, const unsigned int len);
+extern FORB_CDR_Codec *FORB_CDR_codec_init(forb_orb orb);
+extern FORB_CDR_Codec *FORB_CDR_codec_init_static(FORB_CDR_Codec *codec, forb_orb orb);
+extern void FORB_CDR_codec_release_buffer(FORB_CDR_Codec *codec);
+extern void FORB_CDR_codec_free(FORB_CDR_Codec *);
+
+extern CORBA_boolean FORB_CDR_buffer_puts(FORB_CDR_Codec *codec, const void *data, const unsigned int len);
+extern CORBA_boolean FORB_CDR_buffer_gets(FORB_CDR_Codec *codec, void *dest, const unsigned int len);
+
+extern CORBA_boolean FORB_CDR_put_short(FORB_CDR_Codec *codec, CORBA_short s);
+extern CORBA_boolean FORB_CDR_put_ushort(FORB_CDR_Codec *codec, CORBA_unsigned_short us);
+extern CORBA_boolean FORB_CDR_put_long(FORB_CDR_Codec *codec, CORBA_long l);
+extern CORBA_boolean FORB_CDR_put_ulong(FORB_CDR_Codec *codec, CORBA_unsigned_long ul);
+/* #ifdef HAVE_CORBA_LONG_LONG */
+extern CORBA_boolean FORB_CDR_put_long_long(FORB_CDR_Codec *codec, CORBA_long_long ll);
+extern CORBA_boolean FORB_CDR_put_ulong_long(FORB_CDR_Codec *codec, CORBA_unsigned_long_long ull);
+extern CORBA_boolean FORB_CDR_get_ulong_long(FORB_CDR_Codec *codec, CORBA_unsigned_long_long *ul);
+extern CORBA_boolean FORB_CDR_get_long_long(FORB_CDR_Codec *codec, CORBA_long_long *ul);
+/* #endif */
+extern CORBA_boolean FORB_CDR_put_float(FORB_CDR_Codec *codec, CORBA_float f);
+extern CORBA_boolean FORB_CDR_put_double(FORB_CDR_Codec *codec, CORBA_double d);
+extern CORBA_boolean FORB_CDR_put_long_double(FORB_CDR_Codec *codec, CORBA_long_double ld);
+extern CORBA_boolean FORB_CDR_put_octet(FORB_CDR_Codec *codec, CORBA_octet datum);
+extern CORBA_boolean FORB_CDR_put_octets(FORB_CDR_Codec *codec, void *data, unsigned long len);
+extern CORBA_boolean FORB_CDR_put_char(FORB_CDR_Codec *codec, CORBA_char c);
+extern CORBA_boolean FORB_CDR_put_boolean(FORB_CDR_Codec *codec, CORBA_boolean datum);
+extern CORBA_boolean FORB_CDR_put_string(FORB_CDR_Codec *codec, const CORBA_char *str);
+extern CORBA_boolean FORB_CDR_buffer_gets(FORB_CDR_Codec *codec, void *dest, const unsigned int len);
+extern CORBA_boolean FORB_CDR_get_short(FORB_CDR_Codec *codec, CORBA_short *us);
+extern CORBA_boolean FORB_CDR_get_ushort(FORB_CDR_Codec *codec, CORBA_unsigned_short *us);
+extern CORBA_boolean FORB_CDR_get_long(FORB_CDR_Codec *codec, CORBA_long *l);
+extern CORBA_boolean FORB_CDR_get_ulong(FORB_CDR_Codec *codec, CORBA_unsigned_long *ul);
+extern CORBA_boolean FORB_CDR_get_octet(FORB_CDR_Codec *codec, CORBA_octet *datum);
+extern CORBA_boolean FORB_CDR_get_boolean(FORB_CDR_Codec *codec, CORBA_boolean *b);
+extern CORBA_boolean FORB_CDR_get_char(FORB_CDR_Codec *codec, CORBA_char *c);
+extern CORBA_boolean FORB_CDR_get_string(FORB_CDR_Codec *codec, CORBA_char **str);
+extern CORBA_boolean FORB_CDR_get_string_buff(FORB_CDR_Codec *codec, CORBA_char *str);
+extern CORBA_boolean FORB_CDR_get_string_static(FORB_CDR_Codec *codec, CORBA_char **str);
+extern CORBA_boolean FORB_CDR_get_seq_begin(FORB_CDR_Codec *codec, CORBA_unsigned_long *ul);
+extern CORBA_boolean FORB_CDR_get_float(FORB_CDR_Codec *codec, CORBA_float *f);
+extern CORBA_boolean FORB_CDR_get_double(FORB_CDR_Codec *codec, CORBA_double *d);
+
+extern CORBA_boolean FORB_CDR_put_align(FORB_CDR_Codec *codec, unsigned bsize);
+extern CORBA_boolean FORB_CDR_get_align(FORB_CDR_Codec *codec, unsigned bsize);
+
+
+/* serialization functions */
+#define CORBA_short_serialize(x,y)             FORB_CDR_put_short((x),*(y))
+#define CORBA_long_serialize(x,y)              FORB_CDR_put_long((x),*(y))
+#define CORBA_long_long_serialize(x,y)         FORB_CDR_put_long_long((x),*(y))
+#define CORBA_unsigned_short_serialize(x,y)    FORB_CDR_put_ushort((x),*(y))
+#define CORBA_unsigned_long_serialize(x,y)     FORB_CDR_put_ulong((x),*(y))
+#define CORBA_unsigned_long_long_serialize(x,y) FORB_CDR_put_ulong_long((x),*(y))
+#define CORBA_float_serialize(x,y)             FORB_CDR_put_float((x),*(y))
+#define CORBA_double_serialize(x,y)            FORB_CDR_put_double((x),*(y))
+#define CORBA_char_serialize(x,y)              FORB_CDR_put_char((x),*(y))
+#define CORBA_boolean_serialize(x,y)           FORB_CDR_put_boolean((x),*(y))
+#define CORBA_octet_serialize(x,y)             FORB_CDR_put_octet((x),*(y))
+#define CORBA_long_double_serialize(x,y)       FORB_CDR_put_long_double((x),*(y))
+#define CORBA_string_serialize(x,y)            FORB_CDR_put_string((x),*(y))
+
+/* deserialization functions */
+#define CORBA_short_deserialize(x,y)           FORB_CDR_get_short((x),(y))
+#define CORBA_long_deserialize(x,y)            FORB_CDR_get_long((x),(y))
+#define CORBA_long_long_deserialize(x,y)       FORB_CDR_get_long_long((x),(y))
+#define CORBA_unsigned_short_deserialize(x,y)  FORB_CDR_get_ushort((x),(y))
+#define CORBA_unsigned_long_deserialize(x,y)   FORB_CDR_get_ulong((x),(y))
+#define CORBA_unsigned_long_long_deserialize(x,y) FORB_CDR_get_ulong_long((x),(y))
+#define CORBA_float_deserialize(x,y)           FORB_CDR_get_float((x),(y))
+#define CORBA_double_deserialize(x,y)          FORB_CDR_get_double((x),(y))
+#define CORBA_char_deserialize(x,y)            FORB_CDR_get_char((x),(y))
+#define CORBA_boolean_deserialize(x,y)         FORB_CDR_get_boolean((x),(y))
+#define CORBA_octet_deserialize(x,y)           FORB_CDR_get_octet((x),(y))
+#define CORBA_long_double_deserialize(x,y)     FORB_CDR_get_long_double((x),(y))
+#define CORBA_string_deserialize(x,y)          FORB_CDR_get_string((x),(y))
+
+
+#endif /* !_FORB_CDR_H_ */
diff --git a/src/forb/src/cdr_codec.h b/src/forb/src/cdr_codec.h
new file mode 100644 (file)
index 0000000..96cda1b
--- /dev/null
@@ -0,0 +1,63 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   cdr_codec.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:53:47 2008
+ * 
+ * @brief  Definition of FORB_CDR_Codec type.
+ * 
+ * The definition here is incomplete, which means we can use pointers
+ * to this type without having knowledge about internal structorue of
+ * this type.
+ */
+#ifndef FORB_CDR_CODEC_H
+#define FORB_CDR_CODEC_H
+
+typedef struct FORB_CDR_Codec FORB_CDR_Codec;
+
+#endif
diff --git a/src/forb/src/daemon.c b/src/forb/src/daemon.c
new file mode 100644 (file)
index 0000000..a734136
--- /dev/null
@@ -0,0 +1,55 @@
+#include <forb.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* Helper functions to "daemonize" forb servers. To make debugging
+ * easier, we do not detach from terminal. The idea behind daemonizing
+ * is to exit the parent when the server is ready to receive requests,
+ * so that is is not necessary to put delays between invocation of
+ * different servers. */
+
+static int daemon_pipe[2] = { 0, 0 };
+
+void forb_daemon_prepare(const char *pid)
+{
+       pid_t child;
+       int ret;
+       FILE *f;
+       char tmp;
+
+       ret = pipe(daemon_pipe);
+       if (ret) {
+               perror("pipe");
+               exit(1);
+       }
+       child = fork();
+       if (child == -1) {
+               perror("fork");
+               exit(1);
+       }
+       if (child > 0) {
+               close(daemon_pipe[1]);
+               ret = read(daemon_pipe[0], &tmp, 1);
+               if (pid) {
+                       f = fopen(pid, "w");
+                       if (f) {
+                               fprintf(f, "%d\n", child);
+                               fclose(f);
+                       }
+               }
+               exit(ret > 0 ? 0 : 1);
+       } else {
+               close(daemon_pipe[0]);
+       }
+}
+
+/** 
+ * Signal the parent that the daemon is ready so that the parent can
+ * exit().
+ */
+void forb_daemon_ready()
+{
+       if (daemon_pipe[1])
+               write(daemon_pipe[1], "", 1);
+}
+
diff --git a/src/forb/src/discovery.c b/src/forb/src/discovery.c
new file mode 100644 (file)
index 0000000..a0391a9
--- /dev/null
@@ -0,0 +1,273 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   discovery.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Wed May 27 19:28:30 2009
+ * 
+ * @brief  Discovery functions
+ * 
+ */
+
+#include "discovery.h"
+#include <ul_log.h>
+#include "object.h"
+#include <forb/config.h>
+#include "iop.h"
+
+extern UL_LOG_CUST(ulogd_forb_discovery);
+
+GAVL_CUST_NODE_INT_DEC(forb_peer_nolock,/* cust_prefix */
+                      forb_t,          /* cust_root_t */
+                      forb_peer_t,     /* cust_item_t */
+                      forb_server_id,  /* cust_key_t */
+                      peers,           /* cust_root_node */
+                      gnode,           /* cust_item_node */
+                      server_id,       /* cust_item_key */
+                      forb_server_id_cmp)/* cust_cmp_fnc */
+
+GAVL_CUST_NODE_INT_IMP(forb_peer_nolock,/* cust_prefix */
+                      forb_t,          /* cust_root_t */
+                      forb_peer_t,     /* cust_item_t */
+                      forb_server_id,  /* cust_key_t */
+                      peers,           /* cust_root_node */
+                      gnode,           /* cust_item_node */
+                      server_id,       /* cust_item_key */
+                      forb_server_id_cmp);/* cust_cmp_fnc */
+
+int forb_discovery_init(forb_t *forb)
+{
+       if (fosa_mutex_init(&forb->peer_mutex, 0) != 0) return -1;
+       forb_peer_nolock_init_root_field(forb);
+
+       if (fosa_mutex_init(&forb->objkey_mutex, 0) != 0) return -1;
+       forb_objects_nolock_init_root_field(forb);
+       return 0;
+}
+
+static inline void
+forb_peer_insert(forb_t *forb, forb_peer_t *peer)
+{
+       fosa_mutex_lock(&forb->peer_mutex);
+       forb_peer_get(peer);
+       forb_peer_nolock_insert(forb, peer);
+       fosa_mutex_unlock(&forb->peer_mutex);
+}
+
+static inline void
+forb_peer_delete(forb_t *forb, forb_peer_t *peer)
+{
+       fosa_mutex_lock(&forb->peer_mutex);
+       forb_peer_nolock_delete(forb, peer);
+       forb_peer_put(peer);
+       fosa_mutex_unlock(&forb->peer_mutex);
+}
+
+/** 
+ * Finds peer with given @a server_id.
+ * 
+ * @param forb 
+ * @param server_id 
+ * 
+ * @return The found peer or NULL if no peer is found. You have to
+ * call forb_peer_put() after you finish working with the non NULL
+ * retuned value.
+ */
+forb_peer_t *
+forb_peer_find(forb_t *forb, forb_server_id *server_id)
+{
+       forb_peer_t *ret;
+       fosa_mutex_lock(&forb->peer_mutex);
+       ret = forb_peer_nolock_find(forb, server_id);
+       if (ret) {
+               forb_peer_get(ret);
+       }
+       fosa_mutex_unlock(&forb->peer_mutex);
+       return ret;
+}
+
+/** 
+ * Finds the peer with given @a server_id. If the peer is not
+ * currently known (not yet discovered or not available), this
+ * function waits at maximum @a timeout for the peer to be discovered.
+ * 
+ * @param forb 
+ * @param server_id 
+ * @param timeout 
+ * 
+ * @return The peer structure or NULL if the peer is not known even
+ * after the timeout elapses.
+ * 
+ * @note After the returned peer is not needed, forb_peer_put() must
+ * called on it.
+ */
+forb_peer_t *
+forb_peer_find_timed(forb_t *forb, forb_server_id *server_id,
+                    fosa_abs_time_t *timeout)
+{
+       forb_peer_t *peer;
+       bool peer_allocated = false;
+       
+       fosa_mutex_lock(&forb->peer_mutex);
+       peer = forb_peer_nolock_find(forb, server_id);
+       if (!peer && !timeout) goto unlock;
+       if (peer) {
+               forb_peer_get(peer);
+       } else {
+               /* We are the first who want to contact this peer */
+               peer = forb_peer_new();
+               if (!peer) goto unlock;
+               peer->server_id = *server_id;
+               peer->state = FORB_PEER_WANTED;
+               forb_peer_nolock_insert(forb, forb_peer_get(peer));
+               peer_allocated = true;
+       }
+       while (peer->state == FORB_PEER_WANTED) {
+               int ret;
+               /* Wait for the peer to be discovered. */
+               ret = fosa_cond_timedwait(&peer->cond,
+                                         &forb->peer_mutex,
+                                         timeout);
+               if (ret == FOSA_ETIMEDOUT) {
+                       /* No peer discovered within timeout */
+                       if (peer_allocated) {
+                               forb_peer_nolock_delete(forb, peer);
+                               forb_peer_put(peer);
+                       }
+                       forb_peer_put(peer);
+                       peer = NULL;
+                       break;
+               }
+       }
+unlock:        
+       fosa_mutex_unlock(&forb->peer_mutex);
+
+       return peer;
+}
+
+/** 
+ * 
+ * @param port 
+ * @param peer 
+ * @param server_id 
+ * @param addr 
+ * @param orb_id
+ * 
+ * @warning This function has to be called either from receiver thread
+ * of when the recevier thread is not running.
+ */
+void forb_new_peer_discovered(forb_port_t *port, forb_peer_t *peer,
+                        forb_server_id server_id, void *addr,
+                        CORBA_string orb_id)
+{
+       forb_t *forb = port->forb;
+       bool notify_waiters = false;
+       if (peer && peer->state == FORB_PEER_WANTED) {
+               notify_waiters = true;
+       } else if (!peer) {
+               peer = forb_peer_new();
+       }
+       if (!peer)
+               return;
+
+       fosa_mutex_lock(&forb->peer_mutex);
+       peer->server_id = server_id;
+       peer->port = port;
+       peer->addr = addr;
+       peer->orb_id = orb_id;
+       peer->state = FORB_PEER_DISCOVERED;
+       if (notify_waiters) {
+               fosa_cond_broadcast(&peer->cond);
+       } else {
+               forb_peer_nolock_insert(forb, forb_peer_get(peer));
+       }
+       forb_port_peer_ins_tail(port, forb_peer_get(peer));
+       fosa_mutex_unlock(&forb->peer_mutex);
+       {
+               char str[60];
+               ul_logdeb("new peer discovered %s (orb_id '%s')\n",
+                         forb_server_id_to_string(str, &peer->server_id, sizeof(str)),
+                         orb_id);
+       }
+#ifdef CONFIG_FORB_PROTO_INET_DEFAULT
+       if (forb->attr.redistribute_hellos) {
+               forb_peer_t *p;
+               ul_list_for_each(forb_port_peer, port, p) {
+                       if (p != peer &&
+                           forb_server_id_cmp(&p->server_id, &forb->server_id) != 0) {
+                               forb_iop_redistribute_hello_to(p, peer); /* Introduce new peer to others */
+                               forb_iop_redistribute_hello_to(peer, p); /* Introduce other peers to the new one */
+                       }
+               }
+       }
+#endif
+       if (forb->attr.peer_discovery_callback) {
+               forb_orb peer_orb = forb_object_new(forb->orb, &peer->server_id, 0);
+               forb->attr.peer_discovery_callback(peer_orb, orb_id);
+               forb_object_release(peer_orb);
+       }
+       forb_peer_put(peer);
+
+       /* Broadcast our hello packet now */
+       forb_syncobj_signal(&port->hello);
+}
+
+/** 
+ * 
+ * 
+ * @param peer 
+ *
+ * @warning This function has to be called either from receiver thread
+ * of when the recevier thread is not running.
+ */
+void forb_peer_disconnected(forb_peer_t *peer)
+{
+       forb_peer_delete(peer->port->forb, peer);
+       forb_port_peer_delete(peer->port, peer);
+       forb_peer_put(peer);    /* This should release the peer and in case on proto_inet close the socker. */
+}
+
diff --git a/src/forb/src/discovery.h b/src/forb/src/discovery.h
new file mode 100644 (file)
index 0000000..5425e29
--- /dev/null
@@ -0,0 +1,69 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+#ifndef DISCOVERY_H
+#define DISCOVERY_H
+
+#include "peer.h"
+#include "port.h"
+
+int forb_discovery_init(forb_t *forb);
+
+void forb_new_peer_discovered(forb_port_t *port, forb_peer_t *peer,
+                             forb_server_id server_id, void *addr,
+                             CORBA_string orb_id);
+
+
+void forb_peer_disconnected(forb_peer_t *peer);
+
+forb_peer_t *
+forb_peer_find(forb_t *forb, forb_server_id *server_id);
+
+forb_peer_t *
+forb_peer_find_timed(forb_t *forb, forb_server_id *server_id,
+                    fosa_abs_time_t *timeout);
+
+#endif
diff --git a/src/forb/src/exec_req.c b/src/forb/src/exec_req.c
new file mode 100644 (file)
index 0000000..e5b9c76
--- /dev/null
@@ -0,0 +1,122 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+/**
+ * @file   exec_req.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:47:25 2008
+ * 
+ * @brief  Hanlding of requests in executors.
+ * 
+ */
+
+#include "exec_req.h"
+#include "executor.h"
+#include <stdbool.h>
+#include "forb-internal.h"
+#include "object.h"
+#include "iop-idl.h"
+#include <ul_log.h>
+#include "iop.h"
+
+extern UL_LOG_CUST(ulogd_forb_exec_req);
+
+void forb_exec_req_process(forb_exec_req_t *exec_req)
+{
+       FORB_CDR_Codec reply_codec;
+       struct forb_env env;
+       const forb_skel_func *skeletons;
+       forb_t *forb = forb_object_to_forb(exec_req->obj);
+       CORBA_boolean ret;
+       
+       FORB_CDR_codec_init_static(&reply_codec, exec_req->obj->orb);   
+       ret = FORB_CDR_buffer_init(&reply_codec, 4096,
+                             forb_iop_MESSAGE_HEADER_SIZE +
+                             forb_iop_REPLY_HEADER_SIZE);
+       if (!ret) {
+               /* Without codec, we cannot send any reply so return silently. */
+               ul_logerr("No memory for reply buffer\n");
+               return;
+       }
+
+       env.major = FORB_EX_NONE;
+
+       /* Allow the implementation to know about request details
+        * (e.g. source). */
+       exec_req->obj->exec_req = exec_req;
+
+       /* Invoke the skeleton */
+       skeletons = exec_req->obj->interface->skeletons;
+       skeletons[exec_req->method_index](&exec_req->codec,
+                                        &reply_codec,
+                                        exec_req->obj,
+                                        &env);
+       
+       forb_iop_send_reply(forb, &exec_req->source,
+                           &reply_codec,
+                           exec_req->request_id, &env);
+       FORB_CDR_codec_release_buffer(&reply_codec);
+       forb_exec_req_destroy(exec_req);
+}
+
+void forb_exec_req_ins_tail(forb_executor_t *executor,
+                           forb_exec_req_t *exec_req)
+{
+       bool was_empty;
+       fosa_mutex_lock(&executor->mutex);
+       was_empty = forb_exec_req_nolock_is_empty(executor);
+       forb_exec_req_nolock_ins_tail(executor, exec_req);
+       if (was_empty) {
+               fosa_cond_signal(&executor->new_request_in_empty_list);
+       }
+       fosa_mutex_unlock(&executor->mutex);
+}
+
+void forb_exec_req_destroy(forb_exec_req_t *exec_req)
+{
+       forb_object_release(exec_req->obj);
+       FORB_CDR_codec_release_buffer(&exec_req->codec);
+       forb_free(exec_req);
+}
diff --git a/src/forb/src/exec_req.h b/src/forb/src/exec_req.h
new file mode 100644 (file)
index 0000000..57b17ba
--- /dev/null
@@ -0,0 +1,92 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   exec_req.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:21:40 2008
+ * 
+ * @brief  Data type and functions prototypes for requests to executors.
+ * 
+ * 
+ */
+
+#ifndef FORB_EXEC_REQ_H
+#define FORB_EXEC_REQ_H
+
+#include <forb.h>
+#include <forb/cdr_codec.h>
+#include <forb/cdr.h>
+#include <ul_list.h>
+#include "executor.h"
+
+/**
+ * Request for ::forb_executor_t.
+ * 
+ */
+typedef struct forb_exec_req {
+       unsigned request_id;    /**< Request ID. Used to prepare reply message. */
+       forb_server_id source;  /**< Source of this request. */
+       forb_object obj;        /**< Object which is requested */
+       unsigned method_index;  /**< Mehotd number to be invoked on the object @a obj. */
+       FORB_CDR_Codec codec;   /**< Bufffer with serialized request parameters. */
+       ul_list_node_t node;    /**< Node for forb_executor_t::requests. */
+} forb_exec_req_t;
+
+UL_LIST_CUST_DEC(forb_exec_req_nolock, /* cust_prefix */
+                forb_executor_t, /* cust_head_t */
+                forb_exec_req_t, /* cust_item_t */
+                requests, /* cust_head_field */
+                node); /* cust_node_field */
+                
+
+void forb_exec_req_process(forb_exec_req_t *exec_req);
+
+void forb_exec_req_ins_tail(forb_executor_t *executor,
+                           forb_exec_req_t *exec_req);
+void forb_exec_req_destroy(forb_exec_req_t *exec_req);
+
+#endif
diff --git a/src/forb/src/executor.c b/src/forb/src/executor.c
new file mode 100644 (file)
index 0000000..da1a4d7
--- /dev/null
@@ -0,0 +1,175 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   executor.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:18:04 2008
+ * 
+ * @brief  Implementation of executors.
+ */
+
+
+#include "executor.h"
+#include "exec_req.h"
+#include "object.h"
+#include <ul_log.h>
+
+extern UL_LOG_CUST(ulogd_forb_executor);
+
+/** 
+ * Initializes executor.
+ * 
+ * @param executor 
+ * 
+ * @return Zero on success, FOSA error code on error.
+ */
+int forb_executor_init(forb_executor_t *executor)
+{
+       int ret;
+       ret = fosa_mutex_init(&executor->mutex, 0);
+       if (ret) return ret;
+
+       ret = fosa_cond_init(&executor->new_request_in_empty_list);
+       if (ret) return ret;
+
+       forb_exec_req_nolock_init_head(executor);
+       return 0;
+}
+
+void forb_executor_destroy(forb_executor_t *executor)
+{
+       /* TODO: */
+}
+
+/** 
+ * Setup the object @a obj so that requests to it are executed within
+ * the thread of the @a executor.
+ * 
+ * @param executor
+ * @param obj 
+ * 
+ * @return Zero on success, non-zero on error.
+ */
+int forb_executor_register_object(forb_executor_t *executor, forb_object obj)
+{
+       if (!obj || obj->executor)
+               return -1;
+
+       obj->executor = executor;
+       return 0;
+}
+
+/** 
+ * Unregisteres the object @a obj from @a executor.
+ * 
+ * @param executor
+ * @param obj 
+ */
+void forb_executor_unregister_object(forb_executor_t *executor, forb_object obj)
+{
+       if (obj) {
+               obj->executor = NULL;
+       }
+}
+
+/** 
+ * Executor's main loop which executes object implementation methods
+ * upon request.
+ *
+ * The requests are represented by ::forb_exec_req_t and are enqueued
+ * to the executor's request queue by receiver threads of individual
+ * ports (forb_iop_receiver_thread()).
+ * 
+ * @param executor 
+ * 
+ * @return Zero on normal termination, non-zero error codes will be
+ * defined later.
+ */
+int forb_executor_run(forb_executor_t *executor)
+{
+       fosa_mutex_lock(&executor->mutex);
+       while (1) {
+               fosa_cond_wait(&executor->new_request_in_empty_list,
+                              &executor->mutex);
+               while (!forb_exec_req_nolock_is_empty(executor)) {
+                       forb_exec_req_t *exec_req;
+                       exec_req = forb_exec_req_nolock_cut_first(executor);
+                       fosa_mutex_unlock(&executor->mutex);
+
+                       forb_exec_req_process(exec_req);
+
+                       fosa_mutex_lock(&executor->mutex);
+               }
+       }
+       fosa_mutex_unlock(&executor->mutex);
+       return 0;
+}
+
+/** 
+ * Convenience function for executing only one object in one executor.
+ * 
+ * @param obj The object to execute.
+ * 
+ * @return Zero in case of success, error code on error.
+ */
+int forb_execute_object(forb_object obj)
+{
+       forb_executor_t executor;
+       int ret;
+       
+       ret = forb_executor_init(&executor);
+       if (ret) goto error;
+       ret = forb_executor_register_object(&executor, obj);
+       if (ret) goto destroy_and_error;
+       
+       ret = forb_executor_run(&executor);
+
+destroy_and_error:
+       forb_executor_destroy(&executor);
+error:
+       return ret;
+}
diff --git a/src/forb/src/executor.h b/src/forb/src/executor.h
new file mode 100644 (file)
index 0000000..0d08f4f
--- /dev/null
@@ -0,0 +1,88 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+/**
+ * @file   executor.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:19:24 2008
+ * 
+ * @brief  Executor type and prototypes.
+ * 
+ * 
+ */
+
+#ifndef EXECUTOR_H
+#define EXECUTOR_H
+
+#include <fosa.h>
+#include <ul_list.h>
+#include <forb/object_type.h>
+
+/**
+ * Executor structure.
+ *
+ * Executors provide a way for applications to determine which thread
+ * will execute requests for a particular object. After the executor
+ * structure is initialized by forb_executor_init(), several objects
+ * can be registered to it by forb_executor_register_object(). Then a
+ * loop which waits for requests and executes them by calling object
+ * implementations is started by forb_executor_run().
+ */
+typedef struct forb_executor {
+       fosa_mutex_t mutex;     /**< Mutex for protecting forb_executor_t::requests. */
+       fosa_cond_t new_request_in_empty_list; /**< Signaled when a request was added to the empty list. */
+       ul_list_head_t requests; /**< List of pending requests for this executor. */
+} forb_executor_t;
+
+int forb_executor_init(forb_executor_t *executor);
+void forb_executor_destroy(forb_executor_t *executor);
+int forb_executor_register_object(forb_executor_t *executor, forb_object obj);
+void forb_executor_unregister_object(forb_executor_t *executor, forb_object obj);
+int forb_executor_run(forb_executor_t *executor);
+
+int forb_execute_object(forb_object obj);
+
+
+#endif
diff --git a/src/forb/src/forb-idl.idl b/src/forb/src/forb-idl.idl
new file mode 100644 (file)
index 0000000..101ddb6
--- /dev/null
@@ -0,0 +1,21 @@
+/**
+ * @file   forb-idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Mon Oct 13 13:41:54 2008
+ * 
+ * @brief  Remote interface for FORB
+ * 
+ */
+
+
+module forb {
+       /**
+        * Remote interface for FORB obejcts
+        * 
+        * Every FORB provides this interface to remote forbs so that
+        * other FORBs can obtain information about other FORBs.
+        */
+       interface orb {
+               void is_alive(); /**< Empty function intended to check whether the FORB is active or not. */
+       };
+};
diff --git a/src/forb/src/forb-internal.h b/src/forb/src/forb-internal.h
new file mode 100644 (file)
index 0000000..77f3f50
--- /dev/null
@@ -0,0 +1,126 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   forb-internal.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * 
+ * @brief  Declarationd necessary for IDL-generated code and other parts of FORB.
+ *
+ * This header is not intended to be included by applications.
+ * 
+ */
+
+#ifndef FORB_INTERNAL_H
+#define FORB_INTERNAL_H
+
+#include <forb/basic_types.h>
+#include <forb/cdr.h>
+#include <forb.h>
+#include <forb/uuid.h>
+#include <ul_list.h>
+#include <ul_gavlcust.h>
+#include <forb.h>
+#include <string.h>
+#include <forb/server_id.h>
+
+
+/**
+ * Temporary directory for FORB's housekeeping.
+ *
+ * It is used for proto_unix.c sockets and for registered references
+ * (forb_register_reference()).
+ */
+#define FORB_TMP_DIR "/tmp/forb"
+
+#define FORB_METHOD_INDEX(m) (m ## __method_index)
+
+/**
+ * Internal data of every FORB instance.
+ * 
+ */
+typedef struct forb {
+       forb_server_id server_id;
+       char server_id_str[sizeof(forb_server_id)*2+1]; /**< Server ID string - for easier debuggin messages */
+       forb_orb orb;           /**< Object reference of this forb */
+
+       forb_init_attr_t attr;  /**< Initialization attributes */
+
+       fosa_mutex_t request_id_mutex;  /**< Mutex for request_id */
+       CORBA_long request_id;  /**< Value of next sent request_id */
+
+       fosa_mutex_t objkey_mutex; /**< Mutex for objkey and objects */
+       forb_object_key objkey; /**< Objkey value of last created object  */
+       gavl_cust_root_field_t objects; /**< Tree of objects registered with this FORB. */
+
+       //forb_rt rt;           /**< Routing table */
+       //gavl_cust_root_field_t types;
+
+       fosa_mutex_t request_mutex; /**< Mutex for requests */
+       gavl_cust_root_field_t requests; /**< Container for ::forb_request_t */
+
+       fosa_mutex_t port_mutex;
+       ul_list_head_t ports;   /**< Container for ::forb_port_t */
+
+       fosa_mutex_t peer_mutex; /**< Mutex for @a peers */
+       gavl_cust_root_field_t peers; /**< Container for ::forb_peer_t */
+
+       fosa_mutex_t regref_mutex;
+       gavl_cust_root_field_t regrefs; /**< Container for ::forb_regref_t */
+
+       fosa_thread_id_t execution_thread; /**< Thread which executes remote requests for this forb::orb interface. */
+} forb_t;
+
+typedef void (*forb_skel_func)(FORB_CDR_Codec *cin,
+                              FORB_CDR_Codec *cout,
+                              struct _forb_object *obj,
+                              struct forb_env *env);
+
+
+int
+forb_init_tmp_dir(void);
+
+#endif
diff --git a/src/forb/src/forb.c b/src/forb/src/forb.c
new file mode 100644 (file)
index 0000000..2b31722
--- /dev/null
@@ -0,0 +1,567 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   forb.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:57:01 2008
+ * 
+ * @brief  Implementation of basic FORB's functions.
+ * 
+ * 
+ */
+
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE            /* Because of on_exit()  */
+#endif
+#include "proto.h"
+#include "regref.h"
+#include <forb/config.h>
+#include <forb/forb-internal.h>
+#include <forb.h>
+#include "forb-idl.h"
+#include <forb/iop.h>
+#include <forb/object.h>
+#include <forb/uuid.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <ul_gavlcust.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <unistd.h>
+#include "discovery.h"
+#ifdef CONFIG_FORB_PROTO_UNIX
+#include <forb/proto_unix.h>
+#endif
+#ifdef CONFIG_FORB_PROTO_INET_DEFAULT
+#include <forb/proto_inet.h>
+#endif
+#ifdef CONFIG_FCB
+#include <fcb.h>
+#include <fcb_contact_info.h>
+#endif
+#include <fcntl.h>
+
+#ifdef DEBUG
+#define UL_LOGL_DEF UL_LOGL_DEB
+#else
+#define UL_LOGL_DEF UL_LOGL_ERR
+#endif
+#include "log_domains.inc"
+
+extern UL_LOG_CUST(ulogd_forb);
+static int init_ul_log(void);
+
+UL_LOGREG_DOMAINS_INIT_FUNCTION(forb_logreg_domains, forb_logreg_domains_array);
+
+#if 0
+static void
+destroy_forb_on_exit(int exitcode, void *arg)
+{
+       forb_orb orb = arg;
+       forb_destroy(orb);
+}
+#endif
+
+static void
+forb_is_alive(forb_orb _obj, CORBA_Environment *ev)
+{
+       ul_logdeb("%s called\n", __FUNCTION__);
+}
+
+static struct forb_forb_orb_impl forb_implementation = {
+       .is_alive = forb_is_alive,
+};
+
+/**
+ * Prepares #FORB_TMP_DIR directory for use by forb
+ *
+ * @return Zero on succes, -1 on error and errno is set appropriately.
+ */
+int
+forb_init_tmp_dir(void)
+{
+       struct stat st;
+       int ret;
+
+       ret = stat(FORB_TMP_DIR, &st);
+
+       if (ret == 0 && !S_ISDIR(st.st_mode)) {
+               ret = unlink(FORB_TMP_DIR);
+               if (ret) return -1;
+       } else if (ret == 0) {
+               return 0;
+       }
+       return mkdir(FORB_TMP_DIR, 0777);
+}
+
+/** 
+ * Thread for execution of remote requests for a FORB object.
+ * 
+ * @param arg 
+ * 
+ * @return 
+ */
+static void *
+forb_execution_thread(void *arg)
+{
+       forb_orb orb = arg;
+
+       forb_execute_object(orb);
+       return NULL;
+}
+
+#ifdef CONFIG_FCB
+void hack_register_fcb(forb_orb orb, forb_port_t *port)
+{
+       forb_object fcb = forb_object_new(orb, &FCB_SERVER_ID, 1);
+       if (!fcb) {
+               ul_logerr("Cannot allocate FCB reference\n");
+               return;
+       }
+       forb_register_reference(fcb, fres_contract_broker_reg_name);
+       forb_object_release(fcb);
+}
+#else
+#define hack_register_fcb(orb)
+#endif
+
+
+
+forb_orb
+forb_init(int *argc, char **argv[], const struct forb_init_attr *attr)
+{
+       forb_orb orb;
+       forb_t *forb;
+       int ret;
+
+       forb = forb_malloc(sizeof(*forb));
+       if (!forb) goto err;
+       memset(forb, 0, sizeof(*forb));
+
+       /* Initialize ULUT logging facility */
+       init_ul_log();
+       forb_logreg_domains();
+
+       if (attr) {
+               forb->attr = *attr;
+       } else {
+               memset(&forb->attr, 0, sizeof(forb->attr));
+       }
+
+       if (forb_server_id_empty(&forb->attr.fixed_server_id)) {
+               forb_server_id_init(&forb->server_id);
+       } else {
+               forb->server_id = forb->attr.fixed_server_id;
+       }
+       forb_server_id_to_string(forb->server_id_str, &forb->server_id,
+                                sizeof(forb->server_id_str));
+       ul_logdeb("Initializing forb %s\n", forb->server_id_str);
+
+       if (fosa_mutex_init(&forb->request_id_mutex, 0) != 0) goto err2;
+       if (fosa_mutex_init(&forb->port_mutex, 0) != 0) goto err2;
+       forb_port_init_head(forb);
+       
+       if (fosa_mutex_init(&forb->request_mutex, 0) != 0) goto err2;
+       forb_request_nolock_init_root_field(forb);
+
+       if (forb_discovery_init(forb) != 0) goto err2;
+
+       if (fosa_mutex_init(&forb->regref_mutex, 0) != 0) goto err2;
+       forb_regref_nolock_init_root_field(forb);
+
+       ret = forb_init_tmp_dir();
+       if (ret != 0) {
+               ul_logerr("Cannot prepare " FORB_TMP_DIR "\n");
+               return NULL;
+       }
+
+       orb = forb_forb_orb_new(NULL, &forb_implementation, forb);
+       if (!orb) goto err2;
+       /* Server ID must be assigned manualy */
+       orb->server = forb->server_id;
+
+       forb->orb = orb;
+
+       /* Insert our object reference to objects tree, so that we
+        * can accept remote request to our new ORB. */
+       forb_objects_nolock_insert(forb, orb);
+
+       ret = fosa_thread_create(&forb->execution_thread, NULL,
+                                forb_execution_thread, orb);
+       if (ret != 0)
+               goto err2;
+
+       /* FIXME: I do not know how to deregister the exit handler if
+        * forb_destroy() is called manually. */
+       /* on_exit(destroy_forb_on_exit, orb); */
+
+#ifdef CONFIG_FORB_PROTO_UNIX
+       {
+               forb_port_t *port = forb_malloc(sizeof(*port));
+               if (port) {
+                       memset(port, 0, sizeof(*port));
+                       ret = forb_unix_port_init(&port->desc, &forb->server_id);
+                       if (ret) goto err_free_unix;
+                       ret = forb_register_port(orb, port);
+                       if (ret) goto err_free_unix; /* TODO: forb_unix_port_done() */
+                       goto unix_ok;
+               }
+       err_free_unix:
+               free(port);
+               goto err2;
+       unix_ok:;
+       }
+#endif
+#ifdef CONFIG_FORB_PROTO_INET_DEFAULT
+       {
+               forb_port_t *port = forb_malloc(sizeof(*port));
+               if (port) {
+                       struct in_addr listen_on;
+
+                       memset(port, 0, sizeof(*port));
+                       listen_on.s_addr = INADDR_ANY;
+                       ret = forb_inet_port_init(&port->desc, listen_on,
+                                                 forb->attr.fixed_tcp_port);
+                       if (ret) goto err_free_inet;
+                       ret = forb_register_port(orb, port);
+                       if (ret) goto err_free_inet; /* TODO: forb_inet_port_done() */
+                       goto inet_ok;
+               }
+       err_free_inet:
+               free(port);
+               goto err2;
+       inet_ok:;
+               hack_register_fcb(orb, port);
+       }
+#endif
+       return orb;
+
+err2:  forb_free(forb);
+err:   return NULL;
+}
+
+void forb_destroy(forb_orb orb)
+{
+       forb_t *forb = forb_object_to_forb(orb);
+       forb_port_t *port;
+       forb_regref_t *regref;
+
+       pthread_cancel(forb->execution_thread.pthread_id);
+       pthread_join(forb->execution_thread.pthread_id, NULL);
+       
+       /* Unregister all registered references */
+       while ((regref = forb_regref_first(forb))) {
+               forb_unregister_reference(orb, regref->name.str);
+       }
+       
+       ul_list_for_each_cut(forb_port, forb, port) {
+               forb_destroy_port(port);
+       }
+       forb_object_release(orb);
+       forb_free(forb);
+}
+
+/* void */
+/* forb_register_interface(const struct forb_interface *interface) */
+/* { */
+/*     gavl_insert(&type_registry, &interface->node); */
+/* } */
+
+/** 
+ * Initializes server ID variable.
+ * 
+ * @param server_id Serer ID to initialize.
+ */
+void
+forb_server_id_init(forb_server_id *server_id)
+{
+       forb_uuid_generate((forb_uuid_t*)server_id->uuid);
+}
+
+/** 
+ * Checks whether the @a object is stale. Stale object is an object
+ * reference whose server cannot be contacted to handle requests.
+ * 
+ * @param object Object reference to check.
+ * 
+ * @return True if the object is stale, false otherwise.
+ */
+bool forb_object_is_stale(forb_object object)
+{
+       forb_orb remote_orb;
+       struct forb_env env;
+       bool stale = true;
+       
+       remote_orb = forb_get_orb_of(object);
+       if (!remote_orb) {      /* This shohuld never happen */
+               goto err;
+       }
+       /* TODO: Check not only the ORB, but also whether the object
+        * is still registered with the remote orb. */
+       forb_orb_is_alive(remote_orb, &env);
+       if (env.major == FORB_EX_COMM_FAILURE) {
+               /* Orb is not alive */
+               stale = true;
+       } else {
+               if (forb_exception_occurred(&env)) {
+                       ul_logerr("%s: unexpected exception: %s\n", __FUNCTION__, forb_strerror(&env));
+               }
+               stale = false;  
+       }
+
+       forb_object_release(remote_orb);
+err:
+       return stale;
+}
+
+
+/** 
+ * Returns object reference of forb::orb object associated with the
+ * given object.
+ * 
+ * @param obj 
+ * 
+ * @return 
+ */
+forb_orb
+forb_get_orb_of(const forb_object obj)
+{
+       forb_orb orb;
+
+       if (forb_server_id_cmp(&obj->server, &obj->orb->server) == 0) {
+               orb = forb_object_duplicate(obj->orb);
+       } else {
+               orb = forb_object_new(obj->orb, &obj->server, 0);
+       }
+       return orb;
+}
+
+/** 
+ * Returns server ID of an object reference.
+ * 
+ * @param obj 
+ * @param dest 
+ */
+void
+forb_get_server_id(const forb_object obj, forb_server_id *dest)
+{
+       if (obj) {
+               *dest = obj->server;
+       }
+}
+
+
+/** 
+ * Return instance data registered when the object was created by
+ * forb_XXX_new().
+ * 
+ * @param obj Object reference
+ * 
+ * @return Pointer to the registered data.
+ */
+void *
+forb_instance_data(const forb_object obj)
+{
+       return forb_object_instance_data(obj);
+}
+
+/** 
+ * Returns error message correspondings FORB exception.
+ * 
+ * @param env Environemnt
+ * 
+ * @return Non-NULL pointer to a string.
+ */
+const char *
+forb_strerror(CORBA_Environment *env)
+{
+       if (!env) {
+               return "Invalid environemnt";
+       }
+#define ex(e) case FORB_EX_##e: return #e; break;
+       switch (env->major) {
+       ex(NONE);
+       ex(UNKNOWN);
+       ex(BAD_PARAM);
+       ex(NO_MEMORY);
+       ex(IMP_LIMIT);
+       ex(COMM_FAILURE);
+       ex(INV_OBJREF);
+       ex(NO_PERMISSION);
+       ex(INTERNAL);
+       ex(MARSHAL);
+       ex(INITIALIZE);
+       ex(NO_IMPLEMENT);
+       ex(BAD_OPERATION);
+       ex(NO_RESOURCES);
+       ex(NO_RESPONSE);
+       ex(TRANSIENT);
+       ex(FREE_MEM);
+       ex(INV_IDENT);
+       ex(INV_FLAG);
+       ex(DATA_CONVERSION);
+       ex(OBJECT_NOT_EXIST);
+       ex(TIMEOUT);
+       ex(APPLICATION);
+       }
+#undef ex
+       return "Invalid error number";
+}
+
+/** 
+ * Return server id of the requesting application.
+ *
+ * This function should be only called from within interface
+ * implementation,
+ * 
+ * @param[in] obj Object being requested
+ * @param[out] req_source Server ID of the requesting application
+ */
+void
+forb_get_req_source(const forb_object obj, forb_server_id *req_source)
+{
+       if (req_source) {
+               if (obj && obj->exec_req) {
+                       *req_source = obj->exec_req->source;
+               } else {
+                       memset(req_source, 0, sizeof(*req_source));
+               }
+       }
+}
+
+/**
+ * Internal function for allocation of sequence bufers. Used by
+ * forb_sequence_alloc_buf().
+ *
+ * @param seq
+ * @param seq_size
+ * @param buf_pptr
+ * @param maximum_ptr
+ * @param num_elements
+ * @param elem_size
+ *
+ * @return CORBA_TRUE if the allocation was sucessfull, CORBA_FALSE if
+ * it wasn't.
+ */
+CORBA_boolean
+__forb_sequence_alloc_buf_internal(void *seq, size_t seq_size,
+                                  void **buf_pptr, CORBA_unsigned_long *maximum_ptr,
+                                  unsigned num_elements, size_t elem_size)
+{
+       memset(seq, 0, seq_size);
+       /*(seq)._length = 0;*/
+       if (num_elements && elem_size) *buf_pptr = forb_malloc(num_elements * elem_size);
+       else *buf_pptr = NULL;
+       *maximum_ptr = *buf_pptr ? num_elements : 0;
+       return (*buf_pptr != NULL) || (num_elements == 0);
+}
+
+static FILE *forb_ul_log_file;
+static char progname[64] = "";
+
+void
+forb_ul_log_fnc(ul_log_domain_t *domain, int level,
+               const char *format, va_list ap)
+{
+       struct timespec now;
+       if(!(level&UL_LOGL_CONT)) {
+               level&=UL_LOGL_MASK;
+               clock_gettime(CLOCK_MONOTONIC, &now);
+               fprintf(forb_ul_log_file,"%ld.%6ld: ", now.tv_sec, now.tv_nsec/1000);
+               if (progname[0])
+                       fprintf(forb_ul_log_file,"%s: ", progname);
+               if(domain && domain->name)
+                       fprintf(forb_ul_log_file,"%s: ",domain->name);
+       }
+       vfprintf(forb_ul_log_file, format, ap);
+       fflush(forb_ul_log_file);
+}
+
+static int init_ul_log(void)
+{
+       char *s;
+       char *log_fname;
+       int fd;
+       int flg = 0;
+       char path[128];
+
+/*     if(ul_log_output != NULL) */
+/*             return 0; */
+
+       fd = open("/proc/self/cmdline", O_RDONLY);
+       if (fd >= 0) {
+               int ret;
+               ret = read(fd, path, sizeof(path)-1);
+               if (ret > 0) {
+                       path[ret]=0;
+                       s = strrchr(path, '/');
+                       if (s) s++;
+                       else s = path;
+                       strncpy(progname, s, sizeof(progname)-1);
+               }
+               close(fd);
+       }
+
+       if((log_fname=getenv("UL_LOG_FILENAME"))!=NULL){
+               forb_ul_log_file=fopen(log_fname,"a");
+       }
+       if(forb_ul_log_file==NULL)
+               forb_ul_log_file=stderr;
+       
+       if((s=getenv("UL_DEBUG_FLG")) != NULL){
+               flg=atoi(s);
+       }
+
+       ul_log_redir(forb_ul_log_fnc, flg);
+
+       if((s = getenv("UL_LOG_LEVELS")) != NULL)
+               ul_log_domain_arg2levels(s);
+
+       return 0;
+}
diff --git a/src/forb/src/forb.h b/src/forb/src/forb.h
new file mode 100644 (file)
index 0000000..9e26590
--- /dev/null
@@ -0,0 +1,240 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   forb.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Fri Aug 29 09:37:27 2008
+ * 
+ * @brief  Public interface to FORB. To be used by applications (both servers and clients).
+ * 
+ * 
+ */
+
+/**
+@mainpage
+
+@section Introduction
+
+FORB is a CORBA-like middleware build on top of FOSA (FRESCOR
+Operating System Adaptation). Its main purpose is to provide unified
+in-process, inter-process and inter-node communication mechanism
+needed for implementation of FRESCOR in modular way. FORB is heavily
+inspired by CORBA, but provides only a very limited number of CORBA
+features.
+
+FORB supports one communication primitive, which is synchronous call
+of a remote method. This operation is mapped to a local function call,
+so that programmer cannot see the difference between the local and
+remote invocation. FORB implements all of the operations needed for
+such kind of communication which is:
+
+- serialization and deserialization of parameters and return values,
+- communication protocol to pass requests and replies between
+  processes,
+- finding the process, where the remote operation is implemented.
+
+FORB is composed of the two following components:
+- IDL compiler (called @c forb-idl) and
+- FORB runtime represented by @c libforb library.
+
+This documentation documents the @c libforb library. The IDL compiler
+is derived form Orbit project, and its documentation is out of scope
+of this document.
+
+@section Compilation
+
+See README file.
+
+@section Usage
+
+To use FORB in an application, an IDL (Interface Description Language)
+file has to be created first. This IDL file describes the interfaces
+used in the the application, their methods, parameters and types. The
+IDL language is similar to a subset of C language and is defined in <a
+href="http://www.omg.org/spec/CORBA/3.1/Interfaces/PDF/">OMG CORBA
+specification version 3.1, part 1</a> (chapter 7: OMG IDL Syntax and
+Semantics).
+
+An example IDL file called @c myinterface.idl can look like this:
+@include tests-idl/myinterface.idl
+
+It defines the interface called @c myinterface and some other
+(non-basic) types used in interface methods. To implement this
+interface, we process this file with the IDL compiler:
+
+\verbatim
+$ forb-idl myinterface.idl
+\endverbatim
+
+It generates four files: @c myinterface.h, @c myinterface-stubs.c, @c
+myinterface-skels.c and @c myinterface-common.c. 
+
+The code of a server which implements the first two methods of this
+interface could look like this:
+
+@include tests-idl/example_server.c
+
+We have to compile this file and link it with @c -skels.c and @c
+-common.c files and the following libraries (under Linux): forb fosa
+pthread rt ulut.
+
+The client code which uses our implementation of @c myinterface could
+look like this:
+
+@include tests-idl/example_client.c
+
+It has to be compiled and linked with @c myinterface-stubs.c and @c
+myinterface-common.c files and with the following libraries (under
+Linux): forb fosa pthread rt ulut.
+
+Note that in these examples we intentionally skipped checking for
+errors to achieve more readable code.
+*/
+
+
+#ifndef FORB_H
+#define FORB_H
+
+#include <forb/forb-idl.h>
+#include <forb/basic_types.h>
+#include <fosa.h>
+#include <forb/types.h>
+#include <forb/executor.h>
+#include <forb/object_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Incomplete types - declared in forb-internal.h */
+struct forb_interface;
+typedef struct forb_interface forb_interface_t;
+
+typedef struct forb_init_attr {
+       const char *orb_id;             /**< Name of the FORB used for debugging purposes */
+       void (*peer_discovery_callback)(const forb_orb peer_orb, const char *orb_id);
+       void (*peer_dead_callback)(const forb_orb peer_orb, const char *orb_id);
+       uint16_t fixed_tcp_port; /**< If we want FORB's inet protocol to listen on a fixed port... */
+       forb_server_id fixed_server_id; /**< If we do not want the ID to be random. (HACK) */
+       bool redistribute_hellos;
+
+} forb_init_attr_t;
+
+/** 
+ * Initializes FORB. This function has to be called before any other
+ * FORB function.
+ * 
+ * Any command line arguments used by FORB are removed from the array
+ * and @a argc and @a argv are updated accordingly.
+ * 
+ * @param argc a pointer to the number of command line arguments.
+ * @param argv a pointer to the array of command line arguments.
+ * @param attr attributes that control FORB initialization.
+ * 
+ * @return FORB object reference of NULL in case of error.
+ */
+forb_orb forb_init(int *argc, char **argv[], const forb_init_attr_t *attr);
+
+/** 
+ * Deallocates all resources consumed by FORB.
+ *
+ * @note Called automatically on application exit.
+ * 
+ * @param orb FORB object reference to destroy.
+ */
+void forb_destroy(forb_orb orb);
+
+void
+forb_object_release(forb_object obj);
+
+forb_object
+forb_object_duplicate(const forb_object obj);
+
+void *
+forb_instance_data(const forb_object obj);
+
+int
+forb_register_reference(forb_object object, const char *name);
+
+int
+forb_unregister_reference(forb_orb orb, const char *name);
+
+forb_object
+forb_resolve_reference(const forb_orb orb, const char *name);
+
+forb_object
+forb_string_to_object(const forb_orb orb, const char *string);
+
+char *
+forb_object_to_string(const forb_object obj);
+
+bool forb_object_is_stale(forb_object object);
+
+forb_orb
+forb_get_orb_of(const forb_object obj);
+
+void
+forb_get_server_id(const forb_object obj, forb_server_id *dest);
+
+void
+forb_get_req_source(const forb_object obj, forb_server_id *req_source);
+
+const char *
+forb_strerror(CORBA_Environment *env);
+
+void
+forb_daemon_prepare(const char *pid);
+
+void
+forb_daemon_ready();
+
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif
diff --git a/src/forb/src/forb_endian.h b/src/forb/src/forb_endian.h
new file mode 100644 (file)
index 0000000..863312e
--- /dev/null
@@ -0,0 +1,85 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+#ifndef FORB_ENDIAN_H
+#define FORB_ENDIAN_H 1
+
+#include <endian.h>
+#ifdef __BYTE_ORDER
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define WORDS_BIGENDIAN 1
+#endif
+#endif
+
+
+#define FLAG_BIG_ENDIAN 0
+#define FLAG_LITTLE_ENDIAN 1
+
+#if WORDS_BIGENDIAN
+
+# define FLAG_ENDIANNESS FLAG_BIG_ENDIAN
+# define conversion_needed(to_endianness) ((to_endianness)!=FLAG_BIG_ENDIAN)
+
+#else
+
+# define FLAG_ENDIANNESS FLAG_LITTLE_ENDIAN
+# define conversion_needed(to_endianness) ((to_endianness)!=FLAG_LITTLE_ENDIAN)
+
+#endif
+
+static inline 
+void forb_byteswap(uint8_t *outdata,
+                         const uint8_t *data,
+                         uint32_t datalen)
+{
+  const uint8_t *source_ptr = data;
+  uint8_t *dest_ptr = outdata + datalen - 1;
+  while(dest_ptr >= outdata)
+    *dest_ptr-- = *source_ptr++;
+}
+
+
+#endif /* FLAG_ENDIANNESS */
diff --git a/src/forb/src/forb_utils.h b/src/forb/src/forb_utils.h
new file mode 100644 (file)
index 0000000..b630655
--- /dev/null
@@ -0,0 +1,76 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   forb_utils.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:59:57 2008
+ * 
+ * @brief  Miscellaneous FORB utilites.
+ * 
+ * 
+ */
+
+#ifndef FORB_UTILS_H
+#define FORB_UTILS_H
+
+#include <stdlib.h>
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+/** 
+ * Cast a member of a structure out to the containing structure.
+ * 
+ * @param ptr the pointer to the member.
+ * @param type the type of the container struct this is embedded in.
+ * @param member the name of the member within the struct.
+ */
+#define container_of(ptr, type, member) ({                     \
+       const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+       (type *)( (char *)__mptr - offsetof(type,member) );})
+
+
+#endif
diff --git a/src/forb/src/iop-idl.idl b/src/forb/src/iop-idl.idl
new file mode 100644 (file)
index 0000000..3acb452
--- /dev/null
@@ -0,0 +1,107 @@
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners:                //
+//                                                                       //
+//   Universidad de Cantabria,              SPAIN                        //
+//   University of York,                    UK                           //
+//   Scuola Superiore Sant'Anna,            ITALY                        //
+//   Kaiserslautern University,             GERMANY                      //
+//   Univ. Politécnica  Valencia,           SPAIN                       //
+//   Czech Technical University in Prague,  CZECH REPUBLIC               //
+//   ENEA                                   SWEDEN                       //
+//   Thales Communication S.A.              FRANCE                       //
+//   Visual Tools S.A.                      SPAIN                        //
+//   Rapita Systems Ltd                     UK                           //
+//   Evidence                               ITALY                        //
+//                                                                       //
+//   See http://www.frescor.org for a link to partners' websites         //
+//                                                                       //
+//          FRESCOR project (FP6/2005/IST/5-034026) is funded            //
+//       in part by the European Union Sixth Framework Programme         //
+//       The European Union is not liable of any use that may be         //
+//       made of this code.                                              //
+//                                                                       //
+//                                                                       //
+//  This file is part of FORB (Frescor Object Request Broker)            //
+//                                                                       //
+// FORB is free software; you can redistribute it and/or modify it       //
+// under terms of the GNU General Public License as published by the     //
+// Free Software Foundation; either version 2, or (at your option) any   //
+// later version.  FORB is distributed in the hope that it will be       //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty   //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   //
+// General Public License for more details. You should have received a   //
+// copy of the GNU General Public License along with FORB; see file      //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  //
+// Cambridge, MA 02139, USA.                                             //
+//                                                                       //
+// As a special exception, including FORB header files in a file,        //
+// instantiating FORB generics or templates, or linking other files      //
+// with FORB objects to produce an executable application, does not      //
+// by itself cause the resulting executable application to be covered    //
+// by the GNU General Public License. This exception does not            //
+// however invalidate any other reasons why the executable file might be  //
+// covered by the GNU Public License.                                    //
+////////////////////////////////////////////////////////////////////////////
+
+#include "types.idl"
+
+/**
+ * @file   iop-idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:52:08 2008
+ * 
+ * @brief  Definitions for FORB's IOP (Inter-ORB protocol).
+ * 
+ * 
+ */
+
+
+/// FORB namespace
+module forb {
+       /// Inter-ORB protocol namespace
+       module iop {
+               
+               typedef octet message_type;
+
+               const message_type REQUEST = 0;
+               const message_type REPLY   = 1;
+               const message_type HELLO   = 2;
+
+               /// Version of FORB IOP protocol
+               struct version {
+                       octet major, minor;
+               };
+
+               typedef octet message_flags;
+
+               const message_flags LITTLE_ENDIAN = 1;
+
+               /// Common header of all FORB IOP messages
+               struct message_header {
+                       version       proto_version;
+                        message_type  message_type;
+                       message_flags flags;
+                       unsigned long message_size;
+               };
+               const long MESSAGE_HEADER_SIZE = 8;
+
+               /// Header of REQUEST message
+               struct request_header {
+                       unsigned long request_id;
+                       string iface;
+                       object_key objkey;
+                       short method_index;
+                       server_id source; ///< Server ID of request originator
+               };
+
+               typedef unsigned short reply_flags;
+               const reply_flags FLAG_EXCEPTION = 1;
+               /// Header of REPLY message
+               struct reply_header {
+                       unsigned long request_id;
+                       reply_flags flags;
+               };
+               const long REPLY_HEADER_SIZE = 8;
+       };
+};
diff --git a/src/forb/src/iop.c b/src/forb/src/iop.c
new file mode 100644 (file)
index 0000000..5133069
--- /dev/null
@@ -0,0 +1,793 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   iop.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Mon Sep  1 21:51:58 2008
+ * 
+ * @brief  Implementation of Inter-ORB protocol.
+ * 
+ * 
+ */
+#include "iop.h"
+#include <forb/cdr.h>
+#include <forb/object.h>
+#include "proto.h"
+#include <ul_log.h>
+#include "exec_req.h"
+#include <errno.h>
+#include "peer.h"
+#include "discovery.h"
+
+/** Version of the protocol */
+#define VER_MAJOR 0
+#define VER_MINOR 0
+
+#define VER(major, minor) ((major)<<8 || (minor))
+
+extern UL_LOG_CUST(ulogd_forb_iop);
+
+
+CORBA_boolean
+forb_iop_prepend_message_header(FORB_CDR_Codec *codec, forb_iop_message_type mt)
+{
+       CORBA_boolean ret;
+       forb_iop_message_header mh;
+       mh.proto_version.major = VER_MAJOR;
+       mh.proto_version.minor = VER_MINOR;
+       mh.message_type = mt;
+       mh.flags = (codec->data_endian == LittleEndian) ? forb_iop_LITTLE_ENDIAN : 0;
+       mh.message_size = FORB_CDR_data_size(codec);
+       ret = FORB_CDR_buffer_prepend(codec, forb_iop_MESSAGE_HEADER_SIZE);
+       if (ret) {
+               ret = forb_iop_message_header_serialize(codec, &mh);
+       }
+       return ret;
+}
+
+CORBA_boolean
+forb_iop_prepare_request(forb_request_t *req,
+                        char *iface,
+                        unsigned method_ind,
+                        CORBA_Environment *env)
+{
+       CORBA_boolean ret;
+       forb_iop_request_header rh;
+
+       rh.request_id = req->request_id;
+       rh.iface = iface;
+       rh.objkey = forb_object_to_key(req->obj);
+       rh.method_index = method_ind;
+       rh.source = forb_object_to_forb(req->obj)->server_id;
+       ret = forb_iop_request_header_serialize(&req->cdr_request, &rh);
+       if (ret) {
+               /* Request body is 8 byte aligned */
+               ret = FORB_CDR_put_align(&req->cdr_request, 8);
+               char str[50];
+               ul_logdeb("preparing request: id=%d  dest=%s  iface=%s method=%d\n", req->request_id,
+                         forb_server_id_to_string(str, &req->obj->server, sizeof(str)),
+                         iface, method_ind);
+       }
+       return ret;
+}
+
+static CORBA_boolean
+forb_iop_prepare_hello(FORB_CDR_Codec *codec,
+                      const forb_server_id *server_id,
+                      const void *src_addr,
+                      CORBA_boolean (*serialize_addr)(FORB_CDR_Codec *codec, const void *addr),
+                      const CORBA_char *orb_id)
+{
+       if (!forb_server_id_serialize(codec, server_id)) return CORBA_FALSE;
+       if (serialize_addr) {
+               if (!serialize_addr(codec, src_addr)) return CORBA_FALSE;
+       }
+       if (!CORBA_string_serialize(codec, &orb_id)) return CORBA_FALSE;
+       /* All headers must be 8 byte aligned so align the length of
+        * this message */
+       if (!FORB_CDR_put_align(codec, 8)) return CORBA_FALSE; 
+       if (!forb_iop_prepend_message_header(codec, forb_iop_HELLO)) return CORBA_FALSE;
+       return CORBA_TRUE;
+}
+
+int forb_iop_send_hello_to(forb_peer_t *peer)
+{
+       forb_port_t *port = peer->port;
+       FORB_CDR_Codec codec;
+       int ret;
+       FORB_CDR_codec_init_static(&codec, port->forb->orb);
+       if (!FORB_CDR_buffer_init(&codec, 1024, 0))
+               return -1;              
+       if (!FORB_CDR_buffer_reset(&codec, forb_iop_MESSAGE_HEADER_SIZE)) {
+               ret = -1;
+               goto free;
+       }
+       if (!forb_iop_prepare_hello(&codec, &port->forb->server_id,
+                                   port->desc.addr,
+                                   port->desc.proto->serialize_addr,
+                                   port->forb->attr.orb_id)) {
+               ret = -1;
+               goto free;
+       }
+       ret = forb_proto_send(peer, &codec);
+       if (ret > 0) ret = 0;
+free:
+       FORB_CDR_codec_release_buffer(&codec);
+       return ret;
+}
+
+int
+forb_iop_redistribute_hello_to(forb_peer_t *dest, forb_peer_t *peer)
+{
+       forb_port_t *port = peer->port;
+       FORB_CDR_Codec codec;
+       int ret;
+       FORB_CDR_codec_init_static(&codec, port->forb->orb);
+       if (!FORB_CDR_buffer_init(&codec, 1024, 0))
+               return -1;              
+       if (!FORB_CDR_buffer_reset(&codec, forb_iop_MESSAGE_HEADER_SIZE)) {
+               ret = -1;
+               goto free;
+       }
+       if (!forb_iop_prepare_hello(&codec, &peer->server_id,
+                                   peer->addr,
+                                   peer->port->desc.proto->serialize_addr,
+                                   peer->orb_id)) {
+               ret = -1;
+               goto free;
+       }
+       ul_logdeb("redistributing hello of %s (%s) to %s (%s)\n",
+                 ""/*TODO:id*/, peer->orb_id, "", dest->orb_id);
+       ret = forb_proto_send(dest, &codec);
+       if (ret > 0) ret = 0;
+free:
+       FORB_CDR_codec_release_buffer(&codec);
+       return ret;
+}
+
+bool
+forb_iop_process_message_header(forb_iop_message_header *mh, FORB_CDR_Codec *codec)
+{
+       /* FIXME: If we have multiple protocol versions, use different
+        * type (independent from version) for return value instead of
+        * mh */
+       forb_iop_version_deserialize(codec, &mh->proto_version);
+       switch (VER(mh->proto_version.major, mh->proto_version.minor)) {
+               case VER(VER_MAJOR, VER_MINOR):
+                       forb_iop_message_type_deserialize(codec, &mh->message_type);
+                       forb_iop_message_flags_deserialize(codec, &mh->flags);
+                       /* Check whwther the type is meaningfull */
+                       switch (mh->message_type) {
+                               case forb_iop_REQUEST:
+                               case forb_iop_REPLY:
+                               case forb_iop_HELLO:
+                                       break;
+                               default:
+                                       ul_logerr("rcvd wrong message type: %d\n",
+                                                 mh->message_type);
+                                       return false;
+                       }
+                       codec->data_endian = (mh->flags && forb_iop_LITTLE_ENDIAN) ?
+                               LittleEndian : BigEndian;                       
+                       CORBA_unsigned_long_deserialize(codec, &mh->message_size);
+                       return true;
+                       break;                  
+               default:
+                       ul_logerr("rcvd wrong protocol versio: %d.%d\n",
+                                 mh->proto_version.major, mh->proto_version.minor);
+                       return false;
+       }
+}
+
+static inline CORBA_boolean
+forb_exception_serialize(FORB_CDR_Codec *codec, struct forb_env *env)
+{
+       return CORBA_long_serialize(codec, &env->major);
+}
+
+static inline CORBA_boolean
+forb_exception_deserialize(FORB_CDR_Codec *codec, struct forb_env *env)
+{
+       /* TODO: Declare exceptions in IDL and don't typecast here. */
+       return CORBA_long_deserialize(codec, (CORBA_long*)&env->major);
+}
+
+void
+forb_iop_send_reply(forb_t *forb,
+          forb_server_id *dest,
+          FORB_CDR_Codec *codec,
+          CORBA_long request_id,
+          struct forb_env *env)
+{
+       forb_iop_reply_header reply_header;
+       CORBA_boolean ret;
+       forb_peer_t *peer;
+       fosa_abs_time_t timeout;
+       
+       reply_header.request_id = request_id;
+       reply_header.flags = 0;
+       if (forb_exception_occurred(env)) {
+               reply_header.flags |= forb_iop_FLAG_EXCEPTION;
+               FORB_CDR_buffer_reset(codec, forb_iop_MESSAGE_HEADER_SIZE +
+                                            forb_iop_REPLY_HEADER_SIZE);
+               forb_exception_serialize(codec, env);
+       }
+       /* All headers must be 8 byte aligned so align the length of
+        * this message */
+       if (!FORB_CDR_put_align(codec, 8)) {
+               ul_logerr("Not enough space for tail align\n");
+               return;         /* FIXME: handle error (goto above)*/
+       }
+       /* forb_iop_REPLY_HEADER_SIZE equals to 8 even if the real
+        * header is shorter. We want reply data to be 8 byte
+        * aligned */
+       ret = FORB_CDR_buffer_prepend(codec, forb_iop_REPLY_HEADER_SIZE);
+       if (!ret) {
+               goto err;
+       }
+       ret = forb_iop_reply_header_serialize(codec, &reply_header);
+       if (!ret) {
+               goto err;
+       }
+       forb_iop_prepend_message_header(codec, forb_iop_REPLY);
+
+       fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &timeout);
+       timeout = fosa_abs_time_incr(timeout,
+                                    fosa_msec_to_rel_time(1000));
+
+       peer = forb_get_next_hop(forb, dest, &timeout);
+       if (!peer) {
+               char str[60];
+               forb_server_id_to_string(str, dest, sizeof(str));
+               ul_logerr("Reply destination not found: %s\n", str);
+               goto err;
+       } else {
+               char str[60];
+               forb_server_id_to_string(str, dest, sizeof(str));
+               ul_logdeb("sending reply: dest=%s, id=%u\n", str, request_id);
+       }
+       forb_proto_send(peer, codec);
+       forb_peer_put(peer);
+err:
+       ;
+}
+
+static void
+process_request(forb_port_t *port, FORB_CDR_Codec *codec, uint32_t message_size)
+{
+       forb_iop_request_header request_header;
+       CORBA_boolean ret;
+       forb_object obj;
+       size_t n;
+       forb_t *forb = port->forb;
+       struct forb_env env;
+       FORB_CDR_Codec reply_codec;
+       forb_exec_req_t *exec_req;
+       uint32_t req_size, data_size, header_size;
+       char str[32];
+       forb_peer_t *peer;
+
+       data_size = FORB_CDR_data_size(codec);
+       ret = forb_iop_request_header_deserialize(codec, &request_header);
+       if (!ret) {
+               ul_logerr("Malformed request recevied\n");
+               env.major = FORB_EX_COMM_FAILURE;
+               goto out;
+       }
+       ret = FORB_CDR_get_align(codec, 8);
+       if (!ret) {
+               ul_logerr("Malformed request recevied\n");
+               env.major = FORB_EX_COMM_FAILURE;
+               goto out;
+       }
+
+       header_size = data_size - FORB_CDR_data_size(codec);
+       req_size = message_size - header_size;
+
+       ul_logdeb("rcvd request: src=%s, id=%u, iface=%s, method=%hd\n",
+                 forb_server_id_to_string(str, &request_header.source, sizeof(str)),
+                 request_header.request_id,
+                 request_header.iface,
+                 request_header.method_index);
+
+       if (port->new_peer) {
+               /* Request from a new peer was reported by the underlaying protocol */
+               peer = forb_peer_find(port->forb, &request_header.source);
+               if (peer) {
+                       /* We already know this peer */
+                       /* TODO: Can it be in FORB_PEER_WANTED state?
+                        * If yes, we cannot simply igore this. */
+                       ul_logmsg("new_peer was already known\n");
+                       forb_peer_put(port->new_peer);
+                       port->new_peer = NULL;
+               } else {
+                       ul_logdeb("discovered new_peer from incomming connection\n");
+                       peer = port->new_peer;
+                       port->new_peer = NULL;
+                       forb_new_peer_discovered(port, peer, request_header.source,
+                                                peer->addr, peer->orb_id);
+               }
+               
+       }
+       
+       obj = forb_key_to_object(forb, request_header.objkey);
+       if (!obj) {
+               ul_logerr("Nonexistent object key\n");
+               env.major = FORB_EX_OBJECT_NOT_EXIST;
+               goto send_execption;
+       }
+
+       n = strlen(request_header.iface);
+       ret = strncmp(request_header.iface, obj->interface->name, n);
+       forb_free(request_header.iface);
+       request_header.iface = NULL;
+       if (ret != 0) {
+               env.major = FORB_EX_INV_OBJREF;
+               ul_logerr("Object reference has incorrect type\n");
+               goto send_execption;
+       }
+       
+       if (request_header.method_index >= obj->interface->num_methods) {
+               env.major = FORB_EX_INV_IDENT;
+               ul_logerr("To high method number\n");
+               goto send_execption;
+       }
+
+       if (!obj->executor) {
+               env.major = FORB_EX_NO_IMPLEMENT;
+               ul_logerr("No executor for object\n");
+               goto send_execption;
+
+       }
+
+       /* Enqueue execution request */
+       exec_req = forb_malloc(sizeof(*exec_req));
+       if (exec_req) {
+               memset(exec_req, 0, sizeof(exec_req));
+               exec_req->request_id = request_header.request_id;
+               exec_req->source = request_header.source;
+               exec_req->obj = obj;
+               exec_req->method_index = request_header.method_index;
+               /* Copy the request to exec_req */
+               FORB_CDR_codec_init_static(&exec_req->codec, codec->orb);
+               ret = FORB_CDR_buffer_init(&exec_req->codec,
+                                     req_size,
+                                     0);
+               if (!ret) {
+                       env.major = FORB_EX_NO_MEMORY;
+                       ul_logerr("No memory for executor request bufer of size %d (header_size=%d)\n",
+                                 req_size, header_size);
+                       goto send_execption;
+               }
+               exec_req->codec.data_endian = codec->data_endian;
+               FORB_CDR_buffer_gets(codec, exec_req->codec.buffer, req_size);
+               /* TODO: Use better data structure for incomming
+                  buffer to achieve zero-copy behaviour. */
+               forb_exec_req_ins_tail(obj->executor, exec_req);
+       } else {
+               env.major = FORB_EX_NO_MEMORY;
+               ul_logerr("No memory for executor request\n");
+               goto send_execption;
+       }
+       
+out:
+       return;
+       
+send_execption:
+       FORB_CDR_codec_init_static(&reply_codec, codec->orb);   
+       ret = FORB_CDR_buffer_init(&reply_codec, 4096,
+                             forb_iop_MESSAGE_HEADER_SIZE +
+                             forb_iop_REPLY_HEADER_SIZE);
+       if (!ret) {
+               ul_logerr("No memory for exception reply buffer\n");
+               return;
+       }
+
+       forb_iop_send_reply(port->forb, &request_header.source,
+                           &reply_codec, request_header.request_id, &env);
+       FORB_CDR_codec_release_buffer(&reply_codec);
+       /* TODO: relese exec_req etc. */
+}
+
+static void
+process_reply(forb_port_t *port, FORB_CDR_Codec *codec)
+{
+       forb_iop_reply_header rh;
+       forb_t *forb = port->forb;
+       forb_request_t *req;
+
+       forb_iop_reply_header_deserialize(codec, &rh);
+       /* Reply data are 8 byte aligned */
+       FORB_CDR_get_align(codec, 8);
+       ul_logdeb("rcvd reply: id=%u\n", rh.request_id);
+       req = forb_request_find(forb, &rh.request_id);
+       if (!req) {
+               ul_logerr("Received reply to unknown request_id %u\n", rh.request_id);
+               return;
+       }
+       forb_request_delete(forb, req); /* Deregister request from forb */
+
+       if (rh.flags & forb_iop_FLAG_EXCEPTION) {
+               forb_exception_deserialize(codec, req->env);
+       } else {
+               req->cdr_reply = codec;
+       }
+
+       /* Tell the stub where to signal that reply processing is
+        * finished */
+       req->reply_processed = &port->reply_processed;
+
+       /* Resume the stub waiting in forb_wait_for_reply() */
+       forb_syncobj_signal(&req->reply_ready);
+
+       /* Wait for stub to process the results from the codec's buffer */
+       forb_syncobj_wait(&port->reply_processed);
+}
+
+/** 
+ * Process incomming HELLO messages.
+ *
+ * For every incomming HELLO message the peer table is searched
+ * whether it already contains a record for that peer or not. If not,
+ * the new peer is added to the table and another hello message is
+ * sent so that the new peer discovers us quickly.
+ * 
+ * @param port Port, where hello was received
+ * @param codec Buffer with the hello message
+ */
+static void
+process_hello(forb_port_t *port, FORB_CDR_Codec *codec)
+{
+       forb_server_id server_id;
+       void *addr = NULL;
+       forb_peer_t *peer;
+       forb_t *forb = port->forb;
+       CORBA_string peer_orb_id = NULL;
+
+/*     printf("Hello received at port %p\n", port); */
+
+       forb_server_id_deserialize(codec, &server_id);
+       if (port->desc.proto->deserialize_addr) {
+               port->desc.proto->deserialize_addr(codec, &addr);
+       }
+       {
+               char str[60], addrstr[60];
+               if (port->desc.proto->addr2str) {
+                       port->desc.proto->addr2str(addrstr, sizeof(addrstr), addr);
+               } else
+                       addrstr[0] = 0;
+               ul_logdeb("rcvd hello from %s (addr %s)\n",
+                         forb_server_id_to_string(str, &server_id, sizeof(str)),
+                         addrstr);
+       }
+       CORBA_string_deserialize(codec, &peer_orb_id);
+       if (forb_server_id_cmp(&server_id, &forb->server_id) != 0) {
+               peer = forb_peer_find(forb, &server_id);
+               if (peer && peer->state == FORB_PEER_DISCOVERED) {
+                       /* TODO: Update last hello receive time */
+                       if (port->new_peer) {
+                               ul_logdeb("peer already discovered but not connected - replacing\n");
+                               forb_peer_disconnected(peer);
+                               forb_peer_put(peer);
+                               peer = port->new_peer;
+                               port->new_peer = NULL;
+                               forb_new_peer_discovered(port, peer, server_id, addr, peer_orb_id);
+                       } else {
+                               ul_logdeb("peer already discovered - ignoring\n");
+                               if (addr)
+                                       forb_free(addr);
+                               if (peer_orb_id)
+                                       forb_free(peer_orb_id);
+                               forb_peer_put(peer);
+                       }
+               } else {
+                       if (port->new_peer) {
+                               if (peer) {
+                                       ul_logerr("Unahandled case - FORB_PEER_WANTED && port->new_peer\n");
+                                       forb_peer_put(peer);
+                               }
+                               peer = port->new_peer;
+                               port->new_peer = NULL;
+                       }
+
+                       forb_new_peer_discovered(port, peer, server_id, addr, peer_orb_id);
+               }
+       }
+}
+
+static void
+process_message(forb_port_t *port, const forb_iop_message_header *mh,
+               FORB_CDR_Codec *codec)
+{
+       CORBA_long data_size = FORB_CDR_data_size(codec);
+       /* TODO: Check destination address, whether the message is for
+        * us or should be routed. */
+
+       /* TODO: If there is some processing error, skip the rest of
+        * the message according mh.message_size. */
+       switch (mh->message_type) {
+               case forb_iop_REQUEST:
+                       process_request(port, codec, mh->message_size);
+                       break;
+               case forb_iop_REPLY:
+                       process_reply(port, codec);
+                       break;
+               case forb_iop_HELLO:
+                       process_hello(port, codec);
+                       break;
+               default:
+                       ul_logmsg("rcvd unknown message type\n");
+                       break;
+       }
+       if (port->new_peer) {
+               /* If for some reaseon the new_peer was not processed so free it here. */
+               ul_logmsg("Forgotten new_peer\n");
+               forb_peer_put(port->new_peer);
+               port->new_peer = NULL;
+       }
+
+       FORB_CDR_get_align(codec, 8);
+
+       if (FORB_CDR_data_size(codec) != data_size - mh->message_size) {
+               size_t processed = data_size - FORB_CDR_data_size(codec);
+               ul_logmsg("Message of type %d handled incorrectly (size=%d, processed=%zu); fixing\n",
+                         mh->message_type, mh->message_size, processed);
+               ;
+               codec->rptr += mh->message_size - processed;
+       }
+}
+
+/** 
+ * Thread run for every port to receive FORB messages from that port. 
+ * 
+ * @param arg Pointer to ::forb_port_t typecasted to void *.
+ * 
+ * @return Always NULL
+ */
+void *forb_iop_receiver_thread(void *arg)
+{
+       forb_port_t *port = arg;
+       const forb_proto_t *proto = port->desc.proto;
+       FORB_CDR_Codec *c = &port->codec;
+       ssize_t rcvd;
+       size_t len;
+       forb_iop_message_header mh;
+       bool header_received = false;
+
+       while (!port->finish) {
+               if (c->rptr == c->wptr) {
+                       /* The buffer is empty now - start writing from begining*/
+                       FORB_CDR_buffer_reset(c, 0);
+               }
+               /* TODO: If there is not enough space for reception,
+                * we should shift the already received data to the
+                * beginning of the buffer. */
+               rcvd = proto->recv(port,
+                                  &c->buffer[c->wptr],
+                                  c->wptr_max - c->wptr);
+               if (rcvd < 0) {
+                       ul_logerr("recv returned error %zd (%s), exiting\n", rcvd, strerror(errno));
+                       return NULL;
+               }
+               c->wptr += rcvd;
+                c->wptr_last = c->wptr;
+
+               /* While there are some data in the buffer, process them. */
+               while (FORB_CDR_data_size(c) > 0) {
+                       len = FORB_CDR_data_size(c);
+                       /* Wait for and then process message header */
+                       if (!header_received) {
+                               if (len >= forb_iop_MESSAGE_HEADER_SIZE) {
+                                       if (c->rptr % 8 != 0) {
+                                               ul_logerr("Header doesn't start at 8 byte bounday\n");
+                                       }
+                                       header_received = forb_iop_process_message_header(&mh, c);
+                                       if (!header_received) {
+                                               ul_logerr("Wrong header received\n");
+                                               /* TODO: We should probably reset the buffer here */
+                                       }
+                                       len = FORB_CDR_data_size(c);
+                               } else {
+                                       break; /* Wait for more data to arrive*/
+                               }
+                       }
+                       
+                       /* Wait for and then process the message body */
+                       if (header_received) {
+                               if (len >= mh.message_size) {
+                                       process_message(port, &mh, c);
+                                       /* Wait for the next message */
+                                       header_received = false;
+                               } else {
+                                       break; /* Wait for more data to arrive*/
+                               }
+                       }
+               }
+       }
+       return NULL;
+}
+
+static void
+discovery_cleanup(void *codec)
+{
+       FORB_CDR_codec_release_buffer((FORB_CDR_Codec*)codec);
+       /* TODO: Broadcast some kind of bye bye message */
+}
+
+
+/** 
+ * Thread run for every port to broadcast HELLO messages. These
+ * messages are used for a FORB to discover all peers (and in future
+ * also to detect their disconnection).
+ * 
+ * @param arg Pointer to ::forb_port_t typecasted to void *.
+ * 
+ * @return Always NULL
+ */
+void *forb_iop_discovery_thread(void *arg)
+{
+       forb_port_t *port = arg;
+       const forb_proto_t *proto = port->desc.proto;
+       FORB_CDR_Codec codec;
+       fosa_abs_time_t hello_time;
+       fosa_rel_time_t hello_interval = fosa_msec_to_rel_time(1000*proto->hello_interval);
+       int ret;
+
+       FORB_CDR_codec_init_static(&codec, port->forb->orb);
+       FORB_CDR_buffer_init(&codec, 1024, 0);
+
+       pthread_cleanup_push(discovery_cleanup, &codec);
+       
+       /* Next hello interval is now */
+       fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &hello_time);
+       
+       while (!port->finish) {
+               /* Wait for next hello interval or until somebody
+                * signals us. */
+               ret = forb_syncobj_timedwait(&port->hello, &hello_time);
+               /* sem_timedwait would be more appropriate */
+               if (ret == FOSA_ETIMEDOUT) {
+                       hello_time = fosa_abs_time_incr(hello_time, hello_interval);
+               } else if (ret != 0) {
+                       ul_logerr("hello syncobj error: %s\n", strerror(ret));
+               }
+
+               if (port->finish) break;
+
+               FORB_CDR_buffer_reset(&codec, forb_iop_MESSAGE_HEADER_SIZE);
+               forb_iop_prepare_hello(&codec, &port->forb->server_id, port->desc.addr,
+                                      proto->serialize_addr, port->forb->attr.orb_id);
+/*             printf("Broadcasting hello from port %p\n", port);  */
+               proto->broadcast(port, &codec.buffer[codec.rptr],
+                                FORB_CDR_data_size(&codec));
+       }
+
+       pthread_cleanup_pop(1);
+       return NULL;
+}
+
+/** 
+ * Sends REQUEST message to another FORB.
+ *
+ * The request @a req has to be prepared by
+ * forb_iop_prepare_request(). Then, this function adds a message
+ * header, connects to the destination FORB and sends the request.
+ *
+ * If no exception is reported, then the caller must wait for response
+ * by calling forb_wait_for_reply().
+ * 
+ * @param req A request prepared by forb_iop_prepare_request()
+ * @param env Environment for returning exceptions
+ */
+void
+forb_request_send(forb_request_t *req, CORBA_Environment *env)
+{
+       CORBA_boolean ret;
+       forb_peer_t *peer;
+       ssize_t size;
+       size_t len;
+       fosa_abs_time_t timeout;
+       forb_t *forb = forb_object_to_forb(req->obj);
+
+       if (!forb) {
+               env->major = FORB_EX_INTERNAL;
+               return;
+       }
+
+       req->env = env;     /* Remember, where to return exceptions */
+
+       /* All headers must be 8 byte aligned so align the length of
+        * this message */
+       if (!FORB_CDR_put_align(&req->cdr_request, 8)) {
+               env->major = FORB_EX_INTERNAL;
+               ul_logerr("Not enough space for tail align\n");
+               return;
+       }
+
+       ret = forb_iop_prepend_message_header(&req->cdr_request, forb_iop_REQUEST);
+       if (!ret) {
+               /* This should never happen */
+               env->major = FORB_EX_INTERNAL;
+               return;
+       }
+
+       fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &timeout);
+       timeout = fosa_abs_time_incr(timeout,
+                                    fosa_msec_to_rel_time(1000));
+       peer = forb_get_next_hop(forb, &req->obj->server, &timeout);
+       if (!peer) {
+               char str[50];
+               ul_logerr("Cannot find peer to send request for server %s\n",
+                         forb_server_id_to_string(str, &req->obj->server, sizeof(str)));
+               env->major = FORB_EX_COMM_FAILURE;
+               return;
+       }
+       /* Register the request with forb so we can match incomming
+        * reply to this request. */
+       ret = forb_request_insert(forb, req);
+       if (ret <= 0) {
+               ul_logerr("Insert request error %d\n", ret);
+               env->major = FORB_EX_INTERNAL;
+               goto err_peer_put;
+       }
+
+       {
+               char str[50];
+               ul_logdeb("sending request: id=%d  dest=%s\n", req->request_id,
+                         forb_server_id_to_string(str, &req->obj->server, sizeof(str)));
+       }
+       len = FORB_CDR_data_size(&req->cdr_request);
+       fosa_mutex_lock(&peer->send_lock);
+       size = forb_proto_send(peer, &req->cdr_request);
+       fosa_mutex_unlock(&peer->send_lock);
+       if (size <= 0 || size != len) {
+               env->major = FORB_EX_COMM_FAILURE;
+               /* Request is deleted when the stub calls forb_request_destroy() */
+       }
+ err_peer_put:
+       forb_peer_put(peer);
+}
diff --git a/src/forb/src/iop.h b/src/forb/src/iop.h
new file mode 100644 (file)
index 0000000..e257309
--- /dev/null
@@ -0,0 +1,101 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   iop.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 17:00:39 2008
+ * 
+ * @brief  Interface to Inter-ORB Protocol.
+ * 
+ * 
+ */
+
+#ifndef FORB_IOP_H
+#define FORB_IOP_H
+
+#include <forb/iop-idl.h>
+#include <forb/cdr.h>
+#include <forb/request.h>
+#include <forb/peer.h>
+
+CORBA_boolean
+forb_iop_prepend_message_header(FORB_CDR_Codec *codec, forb_iop_message_type mt);
+
+CORBA_boolean
+forb_iop_prepare_request(forb_request_t *req,
+                        char *iface,
+                        unsigned method_ind,
+                        CORBA_Environment *env);
+
+bool
+forb_iop_process_message_header(forb_iop_message_header *mh, FORB_CDR_Codec *codec);
+
+void
+forb_iop_process_message(forb_iop_message_header *mh, FORB_CDR_Codec *codec);
+
+void
+forb_iop_send_reply(forb_t *forb,
+                   forb_server_id *dest,
+                   FORB_CDR_Codec *codec,
+                   CORBA_long request_id,
+                   struct forb_env *env);
+
+void *
+forb_iop_receiver_thread(void *arg);
+void *
+forb_iop_discovery_thread(void *arg);
+
+/* TODO: rename to forb_iop_send_request */
+void
+forb_request_send(forb_request_t *req, CORBA_Environment *env);
+
+int
+forb_iop_send_hello_to(forb_peer_t *peer);
+int
+forb_iop_redistribute_hello_to(forb_peer_t *dest, forb_peer_t *peer);
+
+#endif
diff --git a/src/forb/src/object.c b/src/forb/src/object.c
new file mode 100644 (file)
index 0000000..7fdac27
--- /dev/null
@@ -0,0 +1,323 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   object.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 17:03:06 2008
+ * 
+ * @brief  Functions for manipulation with FORB's object references.
+ * 
+ * 
+ */
+
+#include <forb/forb-internal.h>
+#include <forb/object.h>
+#include <stdio.h>
+#include <forb/cdr_codec.h>
+#include <forb/cdr.h>
+#include "forb_utils.h"
+#include <inttypes.h>
+
+GAVL_CUST_NODE_INT_IMP(forb_objects_nolock /* cust_prefix */,
+                      forb_t /* cust_root_t */,
+                      struct _forb_object /* cust_item_t */,
+                      forb_object_key /* cust_key_t */,
+                      objects /* cust_root_node */,
+                      node /* cust_item_node */,
+                      objkey /* cust_item_key */,
+                      forb_objkey_cmp/* cust_cmp_fnc */);
+
+/** 
+ * Creates a new object reference.
+ * 
+ * @param orb FORB object this object reference is handled by. This
+ * can be NULL only when local forb_orb reference is created in
+ * forb_init().
+ * 
+ * @param server_id Server ID of the remote FORB, where this object is
+ * implemented or NULL if the object is implemented locally by @a orb.
+ * 
+ * @param key Key of the remote object. If server_id is NULL this
+ * value is ignored and objkey is assigned internally.
+ * 
+ * @return FORB object reference of NULL in case of error.
+ */
+forb_object
+forb_object_new(forb_orb orb,
+              forb_server_id *server_id,
+              forb_object_key key)
+{
+       forb_object obj = forb_malloc(sizeof(*obj));
+       if (obj) {
+               memset(obj, 0, sizeof(*obj));
+               forb_ref_init(&obj->ref);
+               obj->orb = orb ? orb : obj;
+               if (server_id) {
+                       /* remote object */
+                       obj->server = *server_id;
+                       obj->objkey = key;
+               } else {
+                       /* local object */
+                       if (orb) {
+                               /* Normal local object */
+                               forb_t *forb = forb_object_to_forb(obj);
+                               obj->server = forb->server_id;
+                               fosa_mutex_lock(&forb->objkey_mutex);
+                               obj->objkey = ++forb->objkey;
+                               /* We do not use object references for tree pointers. */
+                               forb_objects_nolock_insert(forb, obj);
+                               fosa_mutex_unlock(&forb->objkey_mutex);
+                       } else {
+                               /* forb_orb object. The forb_init()
+                                *  function must assign server field
+                                *  and put the object into the
+                                *  forb->objects  */
+                               obj->objkey = 0;
+                       }
+               }
+       }
+       return obj;
+}
+
+/** 
+ * This function does the real release of memory when reference count
+ * is zero.
+ *
+ * @note We add this function the _real suffix because the
+ * forb_object_release() is meant for applications use and we want the
+ * name similar to CORBA_Object_release().
+ */
+static void
+forb_object_release_real(forb_ref_t *ref)
+{
+       forb_object obj = container_of(ref, struct _forb_object, ref);
+       
+       if (obj->orb) {
+               forb_t *forb = forb_object_to_forb(obj);
+               if (forb_server_id_cmp(&obj->server, &forb->server_id) == 0) {
+                       /* Local object - unregister it from FORB. */
+                       forb_objects_delete(forb, obj);
+               }
+       }
+       forb_free(obj);
+}
+
+static inline void forb_object_get(forb_object obj)
+{
+       forb_ref_get(&obj->ref);
+}
+
+static inline void forb_object_put(forb_object obj)
+{
+       forb_ref_put(&obj->ref, forb_object_release_real);
+       /* TODO: Exit executor. Question: Shall the executor have its
+        * own refcount? Is so, how do we know to exit/kill it?
+        * Possible answer: The executor might be notified from here
+        * and then exit if it owns the last reference. */
+}
+
+/** 
+ * Releases all memory associated with a object reference and
+ * deregister the object from FORB.
+ * 
+ * @param obj Object reference to release
+ */
+void forb_object_release(forb_object obj)
+{
+       forb_object_put(obj);
+}
+
+/** 
+ * Returns the object's key.
+ * 
+ * @param obj 
+ * 
+ * @return The key.
+ */
+forb_object_key forb_object_to_key(forb_object obj)
+{
+       return obj->objkey;
+}
+
+/** 
+ * Returns the objects reference of a given key.
+ * 
+ * @param forb 
+ * @param key 
+ * 
+ * @return The object reference or NULL in case the object with a
+ * given key doesn't exist.
+ */
+forb_object forb_key_to_object(forb_t *forb, forb_object_key key)
+{
+       forb_object obj;
+       obj = forb_objects_find(forb, key);
+       return obj;
+}
+
+/** 
+ * Converts object reference to string.
+ * 
+ * @param obj Object reference to convert.
+ * 
+ * @return String, which must be freed by forb_free() or NULL in case
+ * of error.
+ */
+char *
+forb_object_to_string(const forb_object obj)
+{
+       char *str;
+       size_t s;
+       forb_object_key key;
+       char server_id[65];
+       
+       s = 2*sizeof(forb_server_id)+1+2*sizeof(size_t)+1;
+       str = malloc(s);
+       if (!str) {
+               return NULL;
+       }
+
+       forb_server_id_to_string(server_id, &obj->server, s);
+       key = forb_object_to_key(obj);
+       snprintf(str, s, "%s-%"PRIu64, server_id, key);
+
+       return str;
+}
+
+/** 
+ * Creates object reference from string.
+ *
+ * The string should be generated by forb_object_to_string() in the
+ * same or another FORB. When the returned reference is not needed, it
+ * should be freed by forb_object_release().
+ * 
+ * @param orb FORB which should handle the object.
+ * @param string The string returned by forb_object_to_string().
+ * 
+ * @return FORB object reference or NULL in case of error.
+ */
+forb_object
+forb_string_to_object(const forb_orb orb, const char *string)
+{
+       forb_object obj;
+       forb_object_key key;
+       forb_server_id server_id;
+       int ret;
+
+       if (forb_server_id_from_string(&server_id, string) == NULL)
+               return NULL;
+
+       if (string[2*sizeof(server_id)] != '-')
+               return NULL;
+
+       ret = sscanf(&string[2*sizeof(server_id)+1], "%"SCNu64, &key);
+       if (ret == 0 || ret == EOF)
+               return NULL;
+
+       obj = forb_object_new(orb, &server_id, key);
+       
+       return obj;
+}
+
+/** 
+ * Duplicates the object reference.
+ * 
+ * @param obj Object reference to duplicate.
+ * 
+ * @return The new copy of @a obj or NULL in case of error. The
+ * duplicated object should be released later by forb_object_release().
+ */
+forb_object
+forb_object_duplicate(const forb_object obj)
+{
+       if (!obj) {
+               return NULL;
+       }
+       forb_object_get(obj);
+       return obj;
+}
+
+/** 
+ * Serialize the object reference.
+ * 
+ * @param codec 
+ * @param obj 
+ * 
+ * @return CORBA_TRUE on success, CORBA_FALSE on error.
+ */
+CORBA_boolean
+forb_object_serialize(FORB_CDR_Codec *codec, const forb_object *obj)
+{
+       if (!forb_server_id_serialize(codec, &(*obj)->server))
+               return CORBA_FALSE;
+       if (!forb_object_key_serialize(codec, &(*obj)->objkey))
+               return CORBA_FALSE;
+       return CORBA_TRUE;
+}
+
+/** 
+ * Creates the object reference by deserialization from ::FORB_CDR_Codec.
+ * 
+ * @param codec 
+ * @param obj 
+ * 
+ * @return CORBA_TRUE on success, CORBA_FALSE on error.
+ */
+CORBA_boolean
+forb_object_deserialize(FORB_CDR_Codec *codec, forb_object *obj)
+{
+       forb_server_id server_id;
+       forb_object_key objkey;
+       if (!forb_server_id_deserialize(codec, &server_id))
+               return CORBA_FALSE;
+       if (!forb_object_key_deserialize(codec, &objkey))
+               return CORBA_FALSE;
+       if (!codec->orb)
+               return CORBA_FALSE;
+       *obj = forb_object_new(codec->orb, &server_id, objkey);
+       return CORBA_TRUE;
+}
diff --git a/src/forb/src/object.h b/src/forb/src/object.h
new file mode 100644 (file)
index 0000000..fd255cc
--- /dev/null
@@ -0,0 +1,258 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   object.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 17:03:44 2008
+ * 
+ * @brief  Declarations for FORB's object references.
+ * 
+ * 
+ */
+
+#ifndef FORB_OBJECT_H
+#define FORB_OBJECT_H
+
+#include <ul_gavlcust.h>
+#include <forb/forb-internal.h>
+#include <stdbool.h>
+#include <forb/refcnt.h>
+#include <forb/basic_types.h>
+#include <forb/executor.h>
+#include <forb/exec_req.h>
+
+/**
+ * Object reference structure.
+ *
+ * The only ways for applications to create an object reference are:
+ * - call IDL generated forb_<interface>_new() function,
+ * - call forb_string_to_object().
+ * - call forb_get_orb_of()
+ * - call forb_init()
+ *
+ * When the created object is not needed, the application should call
+ * forb_object_release().
+ *
+ * If the object reference is passed as a parameter of interface
+ * method, the same rules as in CORBA C mapping objref_ptr applies,
+ * which is:
+ * 
+ * - if the method needs to store the object reference, it must call
+ *   forb_object_duplicate() and store the duplicate.
+ */
+struct _forb_object {
+       /** @name Fields valid for both local and remote object references */
+       /*@{*/
+       
+       /** Server implementing this object. @see forb::server_id */
+       forb_server_id server;
+       /** Object key of the object. @see forb::object_key */
+       forb_object_key objkey;
+
+       forb_orb orb;           /**< FORB reference */
+       forb_ref_t ref;         /**< Reference count */
+       /*@}*/
+
+       /** @name Fields used only in implementation (server) */
+       /*@{*/
+
+       /** Any data for implementation */
+       void *instance_data;
+
+       /** Description of interface implemented by this object (for
+        * servers); FIXME: What about clients? */
+       const forb_interface_t *interface;
+
+       /** Pointer to the object implementation methods or NULL in
+        * case of remote object. */
+       const void *implementation;
+
+       /** Executor object, which represents the thread the requests
+        * are executed in. */
+       forb_executor_t *executor;
+
+       /**
+        * Pointer to the execute request in case of remote
+        * invocation.
+        *
+        * @warning If the object can be called both localy and
+        * remotely this field may contain wrong value as the local
+        * and remote requests can be executed in parallel, in
+        * different threads. This will be fixed after even local
+        * invocations will be executed through executors. */
+       forb_exec_req_t *exec_req;
+
+       gavl_node_t node;       /**< Node for forb->objects tree */
+       /*@}*/
+};
+
+/**
+ * Description of an IDL interface.
+ *
+ * Instances of this structure are generated by forb-idl (IDL compiler).
+ */
+struct forb_interface {
+       char *name;             /**< Name of the interface */
+       unsigned num_methods;   /**< Number of methods */
+       const forb_skel_func *skeletons; /**< Array of pointers to skeleton functions (one function for every method) */
+       uint32_t type_hash;     /**< Not implemented */
+};
+
+/**
+ * Returns forb_object::instance_data of an object.
+ * 
+ */
+#define forb_object_instance_data(obj) ((obj)->instance_data)
+
+/** Return forb_t from an object reference. */
+static inline forb_t *
+forb_data(forb_orb orb)
+{ return forb_object_instance_data(orb); }
+
+
+/** 
+ * Returns pointer to forb_t from any object reference.
+ * 
+ * @param obj Object reference.
+ * 
+ * @return Pointer to forb_t which handles the @a obj.
+ */
+static inline forb_t *
+forb_object_to_forb(forb_object obj)
+{ return forb_data(obj->orb); }
+
+forb_object_key forb_object_to_key(forb_object obj);
+forb_object forb_key_to_object(forb_t *forb, forb_object_key key);
+
+static inline int forb_objkey_cmp(const forb_object_key *a, const forb_object_key *b)
+{
+       return (*a<*b) ? -1 :
+               ((*a>*b) ? +1 :
+                0);
+}
+
+forb_object
+forb_object_new(forb_orb orb,
+               forb_server_id *server_id,
+               forb_object_key key);
+
+/* Declaration of typesafe function for storing objects in GAVL tree
+ * ordered by object keys. */
+GAVL_CUST_NODE_INT_DEC(forb_objects_nolock /* cust_prefix */,
+                      forb_t /* cust_root_t */,
+                      struct _forb_object /* cust_item_t */,
+                      forb_object_key /* cust_key_t */,
+                      objects /* cust_root_node */,
+                      node /* cust_item_node */,
+                      objkey /* cust_item_key */,
+                      forb_objkey_cmp/* cust_cmp_fnc */);
+
+
+/** 
+ * Deletes object reference of an implementation from forb_t::objects.
+ * 
+ * @param forb 
+ * @param obj 
+ */
+static inline void
+forb_objects_delete(forb_t *forb, forb_object obj)
+{
+       fosa_mutex_lock(&forb->objkey_mutex);
+       forb_objects_nolock_delete(forb, obj);
+       fosa_mutex_unlock(&forb->objkey_mutex);
+}
+
+/** 
+ * Finds implementation of an object with a given key.
+ * 
+ * @param forb 
+ * @param objkey 
+ * 
+ * @return Object references if it exists or NULL otherwise.
+ */
+static inline forb_object
+forb_objects_find(forb_t *forb, forb_object_key objkey)
+{
+       forb_object ret;
+       fosa_mutex_lock(&forb->objkey_mutex);
+       ret = forb_objects_nolock_find(forb, &objkey);
+       ret = forb_object_duplicate(ret);
+       fosa_mutex_unlock(&forb->objkey_mutex);
+       return ret;
+}
+
+/** 
+ * Determines whether the object is local (in-process) or remote.
+ * 
+ * @param obj 
+ * 
+ * @return true if local, false otherwise or in case of invalid object reference.
+ */
+static inline bool
+forb_object_is_local(forb_object obj)
+{
+       return obj && obj->implementation;
+}
+/** 
+ * Determines whether the object is remote.
+ * 
+ * @param obj 
+ * 
+ * @return true if remote, false otherwise or in case of invalid object reference.
+ */
+static inline bool
+forb_object_is_remote(forb_object obj)
+{
+       return obj && (obj->implementation == NULL);
+}
+
+CORBA_boolean
+forb_object_serialize(FORB_CDR_Codec *codec, const forb_object *obj);
+CORBA_boolean
+forb_object_deserialize(FORB_CDR_Codec *codec, forb_object *obj);
+
+#endif
diff --git a/src/forb/src/object_type.h b/src/forb/src/object_type.h
new file mode 100644 (file)
index 0000000..59b8140
--- /dev/null
@@ -0,0 +1,134 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   object_type.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:19:24 2008
+ * 
+ * @brief  Incomplete declarations of forb_object type and all associated stuff.
+ * 
+ * 
+ */
+
+#ifndef FORB_FORB_OBJECT_H
+#define FORB_FORB_OBJECT_H
+
+#include <forb/basic_types.h>
+#include <stdlib.h>
+#include <forb/types.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+struct _forb_object;
+
+/** Opaque object reference type. */
+typedef struct _forb_object *forb_object;
+typedef forb_object CORBA_Object;
+
+#if !defined(_forb_orb_defined)
+#define _forb_orb_defined 1
+typedef forb_object forb_orb;
+#endif
+
+/**
+ * FORB exception types. Inspired by CORBA's standard system
+ * exceptions.
+ */
+enum forb_exception {
+       FORB_EX_NONE,           /* 0 */
+       FORB_EX_UNKNOWN,        /* 1 */
+       FORB_EX_BAD_PARAM,      /* 2 */
+       FORB_EX_NO_MEMORY,      /* 3 */
+       FORB_EX_IMP_LIMIT,      /* 4 */
+       FORB_EX_COMM_FAILURE,   /* 5 */
+       FORB_EX_INV_OBJREF,     /* 6 */
+       FORB_EX_NO_PERMISSION,  /* 7 */
+       FORB_EX_INTERNAL,       /* 8 */
+       FORB_EX_MARSHAL,        /* 9 */
+       FORB_EX_INITIALIZE,     /* 10 */
+       FORB_EX_NO_IMPLEMENT,   /* 11 */
+       FORB_EX_BAD_OPERATION,  /* 12 */
+       FORB_EX_NO_RESOURCES,   /* 13 */
+       FORB_EX_NO_RESPONSE,    /* 14 */
+       FORB_EX_TRANSIENT,      /* 15 */
+       FORB_EX_FREE_MEM,       /* 16 */
+       FORB_EX_INV_IDENT,      /* 17 */
+       FORB_EX_INV_FLAG,       /* 18 */
+       FORB_EX_DATA_CONVERSION,  /* 19 */
+       FORB_EX_OBJECT_NOT_EXIST, /* 20 */
+       FORB_EX_TIMEOUT,          /* 21 */
+       FORB_EX_APPLICATION,      /* 22 */ /**< Application defined exception - TODO: Add minor number to forb_env */
+};
+
+/** 
+ * Environment for FORB invocations.
+ * 
+ */
+struct forb_env {
+       enum forb_exception major; /**< Exception number */
+};
+
+typedef struct forb_env CORBA_Environment;
+
+static inline CORBA_boolean forb_exception_occurred(CORBA_Environment *env)
+{
+       return (env->major != FORB_EX_NONE);
+}
+
+#define forb_malloc(size) malloc(size)
+#define forb_free(ptr) free(ptr)
+
+#define CORBA_malloc(size) forb_malloc(size)
+#define CORBA_free(ptr) forb_free(ptr)
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif
diff --git a/src/forb/src/peer.c b/src/forb/src/peer.c
new file mode 100644 (file)
index 0000000..946674d
--- /dev/null
@@ -0,0 +1,88 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   peer.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 17:30:27 2008
+ * 
+ * @brief  Implementation of peer manipulation functions.
+ * 
+ * 
+ */
+
+#include "peer.h"
+#include "forb_utils.h"
+#include "proto.h"
+
+forb_peer_t *
+forb_peer_new(void)
+{
+       forb_peer_t *peer;
+       
+       peer = forb_malloc(sizeof(*peer));
+       if (peer) {
+               memset(peer, 0, sizeof(*peer));
+               fosa_cond_init(&peer->cond);
+               forb_ref_init(&peer->ref);
+               fosa_mutex_init(&peer->send_lock, 0);
+       }
+       return peer;
+}
+
+void
+forb_peer_release(forb_ref_t *ref)
+{
+       forb_peer_t *peer = container_of(ref, forb_peer_t, ref);
+       if (peer->port &&
+           peer->port->desc.proto->peer_destroy) {
+               peer->port->desc.proto->peer_destroy(peer);
+       }
+       if (peer->addr)
+               forb_free(peer->addr);
+       
+       forb_free(peer);
+}
diff --git a/src/forb/src/peer.h b/src/forb/src/peer.h
new file mode 100644 (file)
index 0000000..d6587f9
--- /dev/null
@@ -0,0 +1,125 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   peer.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 17:31:51 2008
+ * 
+ * @brief  Declarations of peer data structure and functions.
+ * 
+ * 
+ */
+
+#ifndef FORB_PEER_H
+#define FORB_PEER_H
+
+#include <forb/forb-internal.h>
+#include "port.h"
+#include "refcnt.h"
+#include <ul_gavl.h>
+#include <ul_list.h>
+#include <fosa_mutexes_and_condvars.h>
+/**
+ * State of a peer.
+ * 
+ */
+enum forb_peer_state {
+       FORB_PEER_WANTED,       /**< Somebody is waiting for the peer to be discovered. In this state, only @a server_id field is set. */
+       FORB_PEER_DISCOVERED,   /**< The peer is already discovered, so it is addr is known and messages can be sent to him. */
+};
+
+/**
+ * Description of a peer FORB. We consider peers only in one-hop
+ * distance. For more distant forbs, we need to use a routing table.
+ *
+ * @note This structure is reference counted. Use forb_peer_get() when
+ * you copy a pointer to peer and forb_peer_put() when the pointer is
+ * not needed.
+ */
+typedef struct forb_peer {
+        forb_server_id server_id; /**< Server_id of the peer */
+        forb_port_t *port;     /**< Port of this peer is connected to */
+        void *addr;            /**< Protocol specific address of the peer. */
+        char *orb_id;          /**< ORB ID of the peer */
+        void *proto_priv;      /**< Protocol private data (e.g. info about established connection) */
+        gavl_node_t gnode;     /**< Node of forb_t::peers tree */
+        ul_list_node_t lnode;  /**< Node of forb_port_t::peers list */
+        forb_ref_t ref;        /**< Reference count */
+        enum forb_peer_state state;
+        fosa_cond_t cond;      /**< Condition variable for waiting after the peer is discovered. Used together with forb_t::peer_mutex. */
+        fosa_mutex_t send_lock;
+} forb_peer_t;
+
+UL_LIST_CUST_DEC(forb_port_peer, /* cust_prefix */
+                forb_port_t,    /* cust_head_t */
+                forb_peer_t,    /* cust_item_t */
+                peers,          /* cust_head_field */
+                lnode)          /* cust_node_field */
+
+forb_peer_t *
+forb_peer_new(void);
+
+void
+forb_peer_release(forb_ref_t *ref);
+
+static inline forb_peer_t *
+forb_peer_get(forb_peer_t *peer)
+{
+       forb_ref_get(&peer->ref);
+       return peer;
+}
+       
+static inline void
+forb_peer_put(forb_peer_t *peer)
+{
+       forb_ref_put(&peer->ref, forb_peer_release);
+}
+
+void
+forb_peer_delete_by_port(forb_t *forb, forb_port_t *port);
+
+#endif
diff --git a/src/forb/src/port.c b/src/forb/src/port.c
new file mode 100644 (file)
index 0000000..0c54c40
--- /dev/null
@@ -0,0 +1,193 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   port.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 17:36:13 2008
+ * 
+ * @brief  Implementation of port manipulation functions.
+ * 
+ * 
+ */
+
+
+#include "port.h"
+#include "proto.h"
+#include "object.h"
+#include <forb/config.h>
+#include "iop.h"
+#include <ul_log.h>
+#include "discovery.h"
+
+extern UL_LOG_CUST(ulogd_forb_port);
+
+/** 
+ * Registers a new port in FORB and run receiver thread on it to
+ * receive FORB messages through this prot. 
+ * 
+ * @param forb Where to register the new port.
+ * 
+ * @param port Port to register. The @c desc field should be
+ * initialized prior calling this function. The memory for @a port
+ * should be forb_malloced, since forb_free() is called on the port on
+ * destroy operation.
+ *
+ * @return Zero on success, FOSA error code on error.
+ */
+int forb_register_port(forb_orb orb, forb_port_t *port)
+{
+       int ret;
+       forb_t *forb = forb_data(orb);
+       
+       port->forb = forb;
+       port->finish = false;
+
+       forb_port_peer_init_head(port);
+       
+       fosa_mutex_lock(&forb->port_mutex);
+       forb_port_insert(forb, port);
+       fosa_mutex_unlock(&forb->port_mutex);
+
+       forb_syncobj_init(&port->hello, 0);
+       forb_syncobj_init(&port->reply_processed, 0);
+
+       FORB_CDR_codec_init_static(&port->codec, forb->orb);
+       if (!FORB_CDR_buffer_init(&port->codec, CONFIG_FORB_RECV_BUF_SIZE, 0)) {
+               ret = FOSA_ENOMEM;
+               goto err;
+       }
+
+       if (port->desc.proto->register_cb) {
+               port->desc.proto->register_cb(port);
+       }
+       
+       ret = fosa_thread_create(&port->receiver_thread, NULL,
+                                forb_iop_receiver_thread, port);
+       if (ret != 0)
+               goto err2;
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+       /* For reliability reasons, we do not use discovery protocol
+        * when INET is the default communication protocol. */
+       ret = fosa_thread_create(&port->discovery_thread, NULL,
+                                forb_iop_discovery_thread, port);
+       if (ret != 0)
+               goto err3;
+#endif
+       return 0;
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+err3:
+       port->finish = true;
+       /* FIXME: This is Aquosa specific - cancelation should be
+        * added to FOSA. */
+       pthread_cancel(port->receiver_thread.pthread_id);
+       pthread_cancel(port->discovery_thread.pthread_id);
+
+       pthread_join(port->receiver_thread.pthread_id, NULL);
+       pthread_join(port->discovery_thread.pthread_id, NULL);
+#endif
+err2:
+       FORB_CDR_codec_release_buffer(&port->codec);
+err:
+       fosa_mutex_lock(&forb->port_mutex);
+       forb_port_delete(forb, port);
+       fosa_mutex_unlock(&forb->port_mutex);
+       
+       return ret;
+}
+
+/** 
+ * Destroys the port and all resources associated with it.
+ * 
+ * @param port 
+ */
+void forb_destroy_port(forb_port_t *port)
+{
+       forb_t *forb = port->forb;
+       void *thread_return;
+
+       port->finish = true;    /* Exit all the threads */
+       
+       /* FIXME: There is no FOSA API for thread cancelation. */
+       pthread_cancel(port->receiver_thread.pthread_id);
+
+       /* FIXME: Canceling discovery thread sometimes didn't
+        * work. The discovery thread stayed forever in the
+        * pthread_cond_timedwait(). */
+       //pthread_cancel(port->discovery_thread.pthread_id);
+
+       /* Sometimes, cancelation doesn't work and the
+        * discovery_thread hangs in pthread_cond_timedwait
+        * infinitely. */
+       forb_syncobj_signal(&port->hello);
+       
+       pthread_join(port->receiver_thread.pthread_id, &thread_return);
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+       pthread_join(port->discovery_thread.pthread_id, &thread_return);
+#endif
+
+       /* Because of no locking of port->peers, this must be called
+        * after receiver thread is stopped. */
+       forb_peer_t *peer;
+       ul_list_for_each_cut(forb_port_peer, port, peer) {
+               forb_peer_get(peer);
+               forb_peer_disconnected(peer);
+               forb_peer_put(peer);
+       }
+
+       if (port->desc.proto->port_destroy) {
+               port->desc.proto->port_destroy(port);
+       }
+
+       FORB_CDR_codec_release_buffer(&port->codec);
+
+       fosa_mutex_lock(&forb->port_mutex);
+       forb_port_delete(forb, port);
+       fosa_mutex_unlock(&forb->port_mutex);
+
+       /* TODO: reference counting */
+       forb_free(port);
+}
diff --git a/src/forb/src/port.h b/src/forb/src/port.h
new file mode 100644 (file)
index 0000000..b5b97fa
--- /dev/null
@@ -0,0 +1,114 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   port.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 17:36:39 2008
+ * 
+ * @brief  Declarations of port types and functions.
+ * 
+ * 
+ */
+
+#ifndef FORB_PORT_H
+#define FORB_PORT_H
+
+#include <forb/forb-internal.h>
+#include <forb/syncobj.h>
+
+struct forb_proto;
+struct forb_peer;
+
+/**
+ * Description of a port. Needs to be filled for forb_register_port().
+ */
+struct forb_port_desc {
+       const struct forb_proto *proto;   /**< Protocol used on this port */
+       void *proto_priv;                 /**< Protocol specific data */
+       void *addr;                       /**< Port's address in a protocol specific format. */
+};
+
+/**
+ * Represents one (of possibly multiple) ports using a specific
+ * FORB transport protocol (see ::forb_proto).
+ *
+ * Every port runs its own thread for receiving messages
+ * (forb_iop_receiver_thread()) and another thread
+ * (forb_iop_discovery_thread()) for periodic broadcasting of HELLO
+ * messages to discover peers connected to the same network.
+ */
+typedef struct forb_port {
+       struct forb_port_desc desc;       /**< Description of the port */
+       forb_t *forb;                     /**< FORB, this port is registered in. */
+       fosa_thread_id_t receiver_thread; /**< The thread running forb_port_receiver_thread() */
+       fosa_thread_id_t discovery_thread;/**< The thread for periodic sending HELLO messages */
+       forb_syncobj_t hello;             /**< Synchronization object for signaling the discovery thread to send the hello messages now. */
+       forb_syncobj_t reply_processed;   /**< Synchronization object for signaling the receiver thread to continue processing after the reply is processed by a stub. */
+       FORB_CDR_Codec codec;             /**< Receiving buffer for receiver thread */
+       ul_list_node_t node;              /**< Node in forb's port list */
+       ul_list_head_t peers;             /**< Peers discovered on this port by discovery protocol */
+       bool finish;                      /**< True when the threads should finish their execution, false otherwise. */
+
+       /** Peer discovered by another mean than discovery
+        * protocol. This field may be set by the protocol whenever it
+        * receives a message (e.g. request) from a new peer. This is
+        * to overcome limitations of discovery protocol on unreliable
+        * medium. */
+       struct forb_peer *new_peer;
+} forb_port_t;
+
+UL_LIST_CUST_DEC(forb_port,    /* cust_prefix */
+                forb_t,        /* cust_head_t */
+                forb_port_t,   /* cust_item_t */
+                ports,         /* cust_head_field */
+                node)          /* cust_node_field */
+
+int forb_register_port(forb_orb orb, forb_port_t *port);
+void forb_destroy_port(forb_port_t *port);
+
+
+#endif
diff --git a/src/forb/src/proto.c b/src/forb/src/proto.c
new file mode 100644 (file)
index 0000000..3caab33
--- /dev/null
@@ -0,0 +1,112 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+/**
+ * @file   proto.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 17:43:28 2008
+ * 
+ * @brief  
+ * 
+ * 
+ */
+
+#include "proto.h"
+#include <forb/forb-internal.h>
+#include <forb/config.h>
+#include <stdio.h>
+#include <forb/object.h>
+#include <ul_log.h>
+#include "discovery.h"
+
+extern UL_LOG_CUST(ulogd_forb_proto);
+
+ssize_t forb_proto_send(forb_peer_t *peer, FORB_CDR_Codec *codec)
+{
+       
+#if 0
+       {
+               int i, j;
+               char m[1000];
+               i=j=0;
+               while (i<CDR_data_size(codec) && j<sizeof(m)-3) {
+                       if (i>0 && i%4 == 0) {
+                               m[j++] = ' ';
+                       }
+                       sprintf(&m[j], "%02x", codec->buffer[i+codec->rptr]);
+                       j+=2;
+                       i+=1;
+               }
+               ul_logdeb("sending: %s\n", m);
+       }
+#endif
+       
+       return peer->port->desc.proto->send(peer, &codec->buffer[codec->rptr],
+                                           FORB_CDR_data_size(codec));
+}
+
+
+/** 
+ * Finds next hop on the way to the particular server.
+ *
+ * Currently, as routing is not implemented, this function searches
+ * only peers.
+ * 
+ * @param forb Forb to ask.
+ * @param server_id Destination server.
+ * 
+ * @return Next hop peer of NULL, if the destination is not found.
+ * 
+ * @note After the returned peer is not needed, forb_peer_put() must
+ * called on it.
+ */
+forb_peer_t *
+forb_get_next_hop(forb_t *forb, forb_server_id *server_id, fosa_abs_time_t *timeout)
+{
+       forb_peer_t *peer;
+       peer = forb_peer_find_timed(forb, server_id, timeout);
+       return peer;
+
+}
diff --git a/src/forb/src/proto.h b/src/forb/src/proto.h
new file mode 100644 (file)
index 0000000..1fb9d4e
--- /dev/null
@@ -0,0 +1,162 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   proto.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Thu Aug 28 10:36:23 2008
+ * 
+ * @brief  FORB transport protocol declarations
+ * 
+ * 
+ */
+
+#ifndef FORB_PROTO_H
+#define FORB_PROTO_H
+
+#include "forb-internal.h"
+#include "syncobj.h"
+#include "request.h"
+#include <ul_logbase.h>
+#include "port.h"
+#include "peer.h"
+
+typedef struct forb_proto forb_proto_t;
+
+/**
+ * Description of a FORB transport protocol.
+ */
+struct forb_proto {
+       /** Number of seconds between sending of HELLO messages for discovery process */
+       unsigned hello_interval;
+
+       /** 
+        * Called to free any protocol resources associated with the port.
+        * 
+        * @param port The port to be destroyed.
+        * 
+        * @return Zero on success, negatove error code on error.
+        */
+       int (*port_destroy)(forb_port_t *port);
+
+       /** 
+        * Sends data to a peer.
+        *
+        * If the protocol is connection-oriented, the connection data
+        * can be stored at @c port->proto_priv and used by later
+        * requests.
+        * 
+        * @param peer Peer to send data
+        * @param buf Data to send
+        * @param len Length of data to send
+        * 
+        * @return Length of the sent data (should be equal to @a len on
+        * success) or negative error code on error.
+        */
+       ssize_t (*send)(forb_peer_t *peer, const void *buf, size_t len);
+
+       /** 
+        * Called to free any protocol resources associated with the
+        * peer.
+        * 
+        * @param peer Peer to destroy
+        * 
+        * @note The memory allocated by @a deserialize_addr (if any)
+        * is deallocated by FORB and should not be deallocated here.
+        */
+       void (*peer_destroy)(forb_peer_t *peer);
+       /** 
+        * Receives data through a port
+        * 
+        * @param port Port to use 
+        * @param buf Where to store the received data
+        * @param len Length the buffer @a buf
+        * 
+        * @return Length of the received data or negative error code
+        * on error.
+        */
+       ssize_t (*recv)(forb_port_t *port, void *buf, size_t len);
+
+       /** 
+        * Broadcasts/multicasts a message. All FORBs connected the
+        * the network/bus represented by the @a port should receive
+        * it.
+        *
+        * This function is used by peer discovery protocol.
+        * 
+        * @param port Port to use 
+        * @param buf Data to broadcast 
+        * @param len Length of the @a data
+        * 
+        * @return Zero or positive number on success, negative error
+        * code on error.
+        */
+       ssize_t (*broadcast)(forb_port_t *port, const void *buf, size_t len);
+
+       /** Serializes the protocol specific address */
+       CORBA_boolean (*serialize_addr)(FORB_CDR_Codec *codec, const void *addr);
+
+       /** Deserializes the protocol specific address. The memory for
+        * storing the address should be allocated by forb_malloc(). */
+       CORBA_boolean (*deserialize_addr)(FORB_CDR_Codec *codec, void **addr);
+
+       /** Converts protocol specific address to string */
+       size_t (*addr2str)(char *dest, size_t maxlen, const void *addr);
+
+       /**
+        * Callback caled when the port is registered to FORB just
+        * before reception and discovery threads are started.
+        */
+       void (*register_cb)(forb_port_t *port);
+};
+
+ssize_t forb_proto_send(forb_peer_t *peer, FORB_CDR_Codec *codec);
+
+forb_peer_t *
+forb_get_next_hop(forb_t *forb, forb_server_id *server, fosa_abs_time_t *timeout);
+
+
+#endif
diff --git a/src/forb/src/proto_inet.c b/src/forb/src/proto_inet.c
new file mode 100644 (file)
index 0000000..39ff70e
--- /dev/null
@@ -0,0 +1,701 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+#include "proto.h"
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <forb/proto_inet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <sys/epoll.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <ul_log.h>
+#include <unistd.h>
+#include <forb/config.h>
+#include "discovery.h"
+#include <stdlib.h>
+#include <netinet/tcp.h>
+#include "iop.h" /* FIXME: Sending hello should be handled in IOP layer */
+
+/**
+ * @file   proto_inet.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:10:23 2008
+ * 
+ * @brief  FORB transport protocol based on INET family sockets.
+ * 
+ * UDP is used for broadcasts and TCP for requests/replies. There
+ * exist two uni-drectional connections between any two communicating
+ * peers.
+ */
+
+extern UL_LOG_CUST(ulogd_forb_proto_inet);
+
+#define MCAST_PORT 15514       /**< Port used for multicasts */
+#define MCAST_ADDR "225.15.5.14"
+
+/** Address used by inet protocol. All values are stored in network
+ * byte order. */
+struct inet_addr {
+       struct in_addr addr;
+       uint16_t port;          /**< TCP listening port */
+};
+
+/** INET protocol data for ports. */
+struct inet_port {
+       int udp_socket;         /**< Socket for sending and receiving broadcasts */
+       int listen_socket;      /*  */
+       int epoll_fd;           /**< File descriptor used by epoll() in inet_receive(). */
+       struct inet_addr addr;  /**< Address of this port */
+       int last_recv_fd;       /**< Used in inet_recv() to read data longer than receiving buffer */
+       struct in_addr multicast_addr;
+       ul_list_head_t new_peers; /**< List of just connected peers which did not send any data yet. */
+};
+
+UL_LIST_CUST_DEC(inet_port_new_peer, /* cust_prefix */
+                struct inet_port,   /* cust_head_t */
+                forb_peer_t,        /* cust_item_t */
+                new_peers,          /* cust_head_field */
+                lnode)              /* cust_node_field */
+
+
+/** INET protocol data associated with every peer */
+struct inet_peer {
+       int socket;             /**< Connected socket to the peer */
+};
+
+/* static struct inet_port* */
+/* peer_to_inet_port(forb_peer_t *peer) { return peer->port->desc.proto_priv; } */
+
+static CORBA_boolean
+inet_serialize_addr(FORB_CDR_Codec *codec, const void *addr)
+{
+       const struct inet_addr *a = addr;
+       CORBA_unsigned_long haddr = ntohl(a->addr.s_addr);
+       CORBA_unsigned_short hport = ntohs(a->port);
+       CORBA_boolean ret;
+       ret = CORBA_unsigned_long_serialize(codec, &haddr);
+       if (!ret)
+               return ret;
+       return CORBA_unsigned_short_serialize(codec, &hport);
+}
+
+static CORBA_boolean
+inet_deserialize_addr(FORB_CDR_Codec *codec, void **addr)
+{
+       struct inet_addr *a;
+       CORBA_unsigned_long s_addr;
+       CORBA_unsigned_short port;
+       CORBA_boolean ret;
+
+       a = forb_malloc(sizeof(*a));
+       if (!a)
+               return CORBA_FALSE;
+       ret = CORBA_unsigned_long_deserialize(codec, &s_addr);
+       if (!ret)
+               return ret;
+       ret = CORBA_unsigned_short_deserialize(codec, &port);
+       a->addr.s_addr = htonl(s_addr);
+       a->port = htons(port);
+       *addr = a;
+       return ret;
+}
+
+static int
+setnonblocking(int fd);
+
+static int
+setnodelay(int fd)
+{
+       int ret = 0;
+#if 0                          /* For nice graphs in benchmarks */
+       int yes = 1;
+       ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes));
+       if (ret < 0) {
+               ul_logerr("setsockopt(TCP_NODELAY): %s\n", strerror(errno));
+       }
+#endif
+       return ret;
+       
+}
+
+static int
+inet_connect(forb_peer_t *peer)
+{
+       struct inet_peer *ipeer;
+       struct sockaddr_in sa;
+       struct inet_addr *addr = peer->addr;
+       int ret;
+
+       if (!addr) {
+               ul_logerr("No address to connect\n");
+               goto err;
+       }
+       ipeer = forb_malloc(sizeof(*ipeer));
+       if (!ipeer)
+               goto err;
+       ipeer->socket = socket(PF_INET, SOCK_STREAM, 0);
+       if (!ipeer->socket) {
+               ul_logerr("socket(): %s\n", strerror(errno));
+               goto err_free;
+       }
+       sa.sin_family = AF_INET;
+       sa.sin_port = addr->port;
+       sa.sin_addr = addr->addr;
+       ul_logtrash("connect to %s:%u\n", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
+       ret = connect(ipeer->socket, (struct sockaddr*)&sa, sizeof(sa));
+       if (ret) {
+               ul_logerr("connect error: %s\n", strerror(errno));
+               goto err_close;
+       }
+
+       setnonblocking(ipeer->socket);
+       setnodelay(ipeer->socket);
+
+       struct epoll_event ev;
+       struct inet_port *p = peer->port->desc.proto_priv;
+       memset(&ev, 0, sizeof(ev));
+       ev.events = EPOLLIN | EPOLLET;
+       ev.data.fd = ipeer->socket;
+       ret = epoll_ctl(p->epoll_fd, EPOLL_CTL_ADD, ipeer->socket, &ev);
+       if (ret) {
+               ul_logerr("epoll_ctl on connect failed: %s\n", strerror(errno));
+               goto err_close;
+       }
+
+       peer->proto_priv = ipeer;
+
+#ifndef TEST /* FIXME: Move hello to IOP, introduce proto connect callback */
+       ret = forb_iop_send_hello_to(peer);
+       if (ret) {
+               goto err_close;
+       }
+#endif
+
+       return 0;
+err_close:
+       close(ipeer->socket);
+err_free:
+       forb_free(ipeer);
+err:
+       return -1;
+       
+}
+
+static ssize_t
+inet_send(forb_peer_t *peer, const void *buf, size_t len)
+{
+       struct inet_peer *ipeer = peer->proto_priv;
+       ssize_t ret, sent;
+
+       if (!ipeer) {
+               ret = inet_connect(peer);
+               if (ret) {
+                       return ret;
+               }
+               ipeer = peer->proto_priv;
+       }
+
+       sent = 0;
+       ul_logtrash("send fd=%d len=%zu\n", ipeer->socket, len);
+       do {
+               ret = send(ipeer->socket, buf, len, 0);
+               if (ret < 0) {
+                       ul_logerr("send error: %s\n", strerror(errno));
+                       return ret;
+               }
+               sent += ret;
+               buf += ret;
+               len -= ret;
+       } while (len > 0);
+
+       return sent;
+}
+
+/*----------------------------------------------------------------------
+ Portable function to set a socket into nonblocking mode.
+ Calling this on a socket causes all future read() and write() calls on
+ that socket to do only as much as they can immediately, and return 
+ without waiting.
+ If no data can be read or written, they return -1 and set errno
+ to EAGAIN (or EWOULDBLOCK).
+ Thanks to Bjorn Reese for this code.
+----------------------------------------------------------------------*/
+int setnonblocking(int fd)
+{
+    int flags;
+
+    /* If they have O_NONBLOCK, use the Posix way to do it */
+#if defined(O_NONBLOCK)
+    /* Fixme: O_NONBLOCK is defined but broken on SunOS 4.1.x and AIX 3.2.5. */
+    if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
+        flags = 0;
+    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+#else
+    /* Otherwise, use the old way of doing it */
+    flags = 1;
+    return ioctl(fd, FIOBIO, &flags);
+#endif
+}     
+
+static int
+inet_accept_connection(forb_port_t *port)
+{
+       struct inet_port *p = port->desc.proto_priv;
+       int client;
+       struct sockaddr_in addr;
+       socklen_t addrlen = sizeof(addr);
+       struct epoll_event ev;
+       int ret;
+       forb_peer_t *peer;
+                               
+       client = accept(p->listen_socket, (struct sockaddr *) &addr, &addrlen);
+       if (client < 0){
+               //perror("accept");
+               return -1;
+       }
+       ret = setnonblocking(client);
+       if (ret) {
+               close(client);
+               return -1;
+       }
+       setnodelay(client);
+
+       peer = forb_peer_new();
+       if (peer) {
+               struct inet_peer *ipeer;
+
+               ipeer = forb_malloc(sizeof(*ipeer));
+               if (ipeer) {
+                       ipeer->socket = client;
+                       peer->proto_priv = ipeer;
+                       peer->port = port;
+                       peer->state = FORB_PEER_DISCOVERED;
+                       inet_port_new_peer_insert(p, peer);
+               } else {
+                       forb_peer_put(peer);
+               }
+       }
+       
+       memset(&ev, 0, sizeof(ev));
+       ev.events = EPOLLIN | EPOLLET;
+       ev.data.fd = client;
+       return epoll_ctl(p->epoll_fd, EPOLL_CTL_ADD, client, &ev);
+}
+
+static ssize_t
+inet_recv(forb_port_t *port, void *buf, size_t len)
+{
+       struct inet_port *iport = port->desc.proto_priv;
+#if 1
+       struct epoll_event ev;
+       ssize_t ret;
+       int nfds;
+       forb_peer_t *peer;
+       bool exported_new_peer = false;
+       
+       for (;;) {
+               if (iport->last_recv_fd == -1) {
+                       nfds = epoll_wait(iport->epoll_fd, &ev, 1, -1);
+                       if (nfds == -1 && errno == EINTR)
+                               continue;
+                       if (nfds < 1)
+                               return -1;
+                       if (ev.data.fd == iport->listen_socket) {
+                               ret = inet_accept_connection(port);
+                               if (ret) {
+                                       ul_logerr("inet_accept_connection error: %s\n", strerror(errno));
+                                       return -1;
+                               } else
+                                       continue;
+                       } else {
+                               iport->last_recv_fd = ev.data.fd;
+                       }
+               }
+               /* Check for first reception form a just connected peer */
+               ul_list_for_each(inet_port_new_peer, iport, peer) {
+                       struct inet_peer *ipeer = peer->proto_priv;
+                       //printf("checking new peer with fd=%d\n", ipeer->socket);
+                       if (ipeer->socket == iport->last_recv_fd) {
+                               inet_port_new_peer_delete(iport, peer);
+
+                               if (port->new_peer) forb_peer_put(peer);
+
+                               /* Let the upper layer assign forb ID
+                                * to this peer according to the request*/
+                               port->new_peer = peer;
+                               exported_new_peer = true;
+                               break;
+                       }
+               }
+
+               //printf("recv fd=%d\n", iport->last_recv_fd);
+               ret = recv(iport->last_recv_fd, buf, len, 0);
+               if (ret == -1) {
+                       if (exported_new_peer) {
+                               forb_peer_put(peer);
+                               port->new_peer = NULL;
+                       }
+                       if (errno != EAGAIN) {
+                               ul_logerr("recv fd=%d error: %s\n", iport->last_recv_fd, strerror(errno));
+                       }
+                       iport->last_recv_fd = -1;
+                       continue;
+               }
+               if (ret == 0) {
+                       if (exported_new_peer) {
+                               forb_peer_put(peer);
+                               port->new_peer = NULL;
+                       }
+                       ul_logtrash("recv fd=%d disconnect\n", iport->last_recv_fd);
+                       ul_list_for_each(forb_port_peer, port, peer) {
+                               struct inet_peer *ipeer = peer->proto_priv;
+                               if (ipeer && ipeer->socket == iport->last_recv_fd) {
+                                       forb_peer_disconnected(peer);
+                                       break;
+                               }
+                       }
+                       iport->last_recv_fd = -1;
+                       continue;
+               }
+               ul_logtrash("recv fd=%d len=%zd\n", iport->last_recv_fd, ret);
+               return ret;
+       }
+#else
+       return recv(iport->udp_socket, buf, len, 0);    
+#endif
+}
+
+static int
+inet_port_destroy(forb_port_t * port)
+{
+       struct inet_port *pd = port->desc.proto_priv;
+       close(pd->epoll_fd);
+       close(pd->udp_socket);
+       close(pd->listen_socket);
+       forb_free(pd);
+       return 0;
+}
+
+static ssize_t
+inet_broadcast(forb_port_t *port, const void *buf, size_t len)
+{
+       struct inet_port *p = port->desc.proto_priv;
+       struct sockaddr_in addr;
+       ssize_t ret;
+       
+       addr.sin_family = AF_INET;
+       addr.sin_port = htons(MCAST_PORT);
+       addr.sin_addr = p->multicast_addr;
+       
+       ret = sendto(p->udp_socket, buf, len, 0,
+                    (struct sockaddr*)&addr, sizeof(addr));
+       return ret;
+}
+
+static void
+inet_peer_destroy(forb_peer_t *peer)
+{
+       struct inet_peer *ipeer = peer->proto_priv;
+       if (ipeer) {
+               peer->proto_priv = NULL;
+               ul_logtrash("destroying peer fd=%d (orb_id=%s)\n",
+                           ipeer->socket, peer->orb_id);
+               close(ipeer->socket);
+               free(ipeer);
+       }
+}
+
+size_t inet_addr2str(char *dest, size_t maxlen, const void *addr)
+{
+       const struct inet_addr *a = addr;
+       size_t ret = 0;
+       if (addr) {
+               snprintf(dest, maxlen, "%s:%d", inet_ntoa(a->addr), ntohs(a->port));
+       }
+       return ret;
+}
+
+#if CONFIG_FCB && CONFIG_FORB_PROTO_INET_DEFAULT
+
+#include <fcb.h>
+#include <fcb_contact_info.h>
+
+static void inet_register_cb(forb_port_t *port)
+{
+       struct inet_addr *ia;
+       
+       ia = malloc(sizeof(*ia));
+       if (!ia) return;
+
+       char *fcb_addr = getenv("FCB_ADDR");
+       if (!fcb_addr) fcb_addr = "127.0.0.1";
+       ia->addr.s_addr = inet_addr(fcb_addr);
+       ia->port = htons(FCB_TCP_PORT);
+       forb_new_peer_discovered(port, NULL, FCB_SERVER_ID, ia, "");
+}
+#else
+#define inet_register_cb NULL
+#endif
+
+static const forb_proto_t proto_inet = {
+       .hello_interval = 40 /* seconds */,
+       .port_destroy = inet_port_destroy,
+       .peer_destroy = inet_peer_destroy,
+       .send = inet_send,
+       .recv = inet_recv,
+       .broadcast = inet_broadcast,
+       .serialize_addr = inet_serialize_addr,
+       .deserialize_addr = inet_deserialize_addr,
+       .addr2str = inet_addr2str,
+       .register_cb = inet_register_cb,
+};
+
+#define MAX_INTERFACES 10
+int get_local_address(int sock, struct in_addr *addr)
+{
+       struct ifconf  ifc;
+       struct ifreq   *ifr, req[MAX_INTERFACES];
+       char *env;
+       bool loopback = false;
+       int ret;
+       struct in_addr env_addr;
+       
+       env = getenv("FORB_EXTERNAL_IP");
+       if (env) {
+               if (inet_aton(env, &env_addr) == 0) {
+                       ul_logerr("Cannot convert FORB_EXTERNAL_IP\n");
+                       errno = EINVAL;
+                       return -1;
+               }
+       }
+
+       ifc.ifc_len = sizeof(req);
+       ifc.ifc_req = req;
+
+       if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
+               return -1;
+       for (ifr = req; ifr < &req[MAX_INTERFACES]; ifr++) {
+               struct sockaddr_in ia;
+               memcpy(&ia, &ifr->ifr_addr, sizeof(ia));
+               ret = ioctl(sock, SIOCGIFFLAGS, ifr);
+               if ((ret == 0) && (ifr->ifr_flags & IFF_UP)) {
+                       if (env && env_addr.s_addr == ia.sin_addr.s_addr) {
+                               *addr = env_addr;
+                               return 0;
+                       }
+                       if (!(ifr->ifr_flags & IFF_LOOPBACK)) {
+                               if (!env) {
+                                       *addr = ia.sin_addr;
+                                       return 0;
+                               }
+                       } else {
+                               *addr = ia.sin_addr;
+                               loopback = true;
+                       }
+               }
+       }
+       if (env) {
+               ul_logerr("FORB_EXTERNAL_IP doesn't match local interface\n");
+               errno = ENODEV;
+               return -1;
+       }
+       if (loopback)
+               return 0;
+       else
+               return -1;
+}
+
+/** 
+ * Initializes INET protocol port.
+ * 
+ * @param port_desc Port description to initialize.
+ * @return Zero on success, -1 on error and errno is set
+ * appropriately.
+ */
+int
+forb_inet_port_init(struct forb_port_desc *port_desc, struct in_addr listen_on,
+                   uint16_t port)
+{
+       int ret;       
+       struct inet_port *port_priv;
+       struct sockaddr_in addr;
+       socklen_t len;
+       struct epoll_event ev;
+       
+       port_priv = forb_malloc(sizeof(*port_priv));
+       if (!port_priv)
+               return -1;
+
+       memset(port_priv, 0, sizeof(*port_priv));
+       port_priv->last_recv_fd = -1;
+       inet_port_new_peer_init_head(port_priv);
+       
+       /* Initialize UDP multicast socket */
+       port_priv->udp_socket = socket(PF_INET, SOCK_DGRAM, 0);
+       if (port_priv->udp_socket == -1) goto err_free;
+       
+       int yes = 1;
+       ret = setsockopt(port_priv->udp_socket, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));
+       if (ret)
+               goto err_close_udp;
+
+       int reuse = 1;
+       setsockopt(port_priv->udp_socket, SOL_SOCKET, SO_REUSEADDR, (int *) &reuse, sizeof(reuse));
+       if (ret)
+               goto err_close_udp;
+
+       setnonblocking(port_priv->udp_socket);
+
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+       struct ip_mreq mreq;
+       inet_aton(MCAST_ADDR, &port_priv->multicast_addr);
+       mreq.imr_multiaddr = port_priv->multicast_addr;
+       mreq.imr_interface.s_addr = INADDR_ANY;
+       ret = setsockopt(port_priv->udp_socket, IPPROTO_IP,
+                        IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+       if (ret)
+               goto err_close_udp;
+#endif
+
+       addr.sin_family = AF_INET;
+       addr.sin_port = htons(MCAST_PORT);
+       addr.sin_addr = port_priv->multicast_addr;
+
+       ret = bind(port_priv->udp_socket, (struct sockaddr *)&addr, sizeof(addr));
+       if (ret != 0) goto err_close_udp;
+
+       char loop = 1;
+       unsigned loop_size = sizeof(loop);
+       ret = setsockopt(port_priv->udp_socket, IPPROTO_IP,
+                        IP_MULTICAST_LOOP, &loop, loop_size);
+       if (ret)
+               goto err_close_udp;
+       
+
+       /* Initialize TCP socket */
+       port_priv->listen_socket = socket(PF_INET, SOCK_STREAM, 0);
+       if (port_priv->listen_socket == -1) goto err_close_udp;
+
+       reuse = 1;
+       setsockopt(port_priv->listen_socket, SOL_SOCKET, SO_REUSEADDR, (int *) &reuse, sizeof(reuse));
+       if (ret)
+               goto err_close_listen;
+
+       addr.sin_family = AF_INET;
+       addr.sin_port = htons(port);
+       addr.sin_addr = listen_on;
+       ret = bind(port_priv->listen_socket, (struct sockaddr *)&addr, sizeof(addr));
+       if (ret != 0) goto err_close_listen;
+       if (setnonblocking(port_priv->listen_socket))
+               goto err_close_listen;
+
+       ret = listen(port_priv->listen_socket, 10);
+       if (ret)
+               goto err_close_listen;
+
+       /* Determine our address and port*/
+       len = sizeof(addr);
+       ret = getsockname(port_priv->listen_socket, (struct sockaddr *)&addr, &len);
+       if (ret) {
+               ul_logerr("Non-loopback inet address not found\n");
+               goto err_close_listen;
+       }
+
+       port_priv->addr.port = addr.sin_port;
+       if (listen_on.s_addr == INADDR_ANY) {
+               if (get_local_address(port_priv->listen_socket, &port_priv->addr.addr)) {
+                       goto err_close_listen;
+               }
+       } else
+               port_priv->addr.addr = listen_on;
+
+       /* Initialize epoll descriptor */
+       port_priv->epoll_fd = epoll_create(10);
+       if (port_priv->epoll_fd == -1)
+               goto err_close_listen;
+
+       memset(&ev, 0, sizeof(ev));
+       ev.events = EPOLLIN | EPOLLET;
+       ev.data.fd = port_priv->listen_socket;
+       ret = epoll_ctl(port_priv->epoll_fd, EPOLL_CTL_ADD,
+                       port_priv->listen_socket, &ev);
+       if (ret)
+               goto err_close_epoll;
+
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT 
+       ev.events = EPOLLIN | EPOLLET;
+       ev.data.fd = port_priv->udp_socket;
+       ret = epoll_ctl(port_priv->epoll_fd, EPOLL_CTL_ADD,
+                       port_priv->udp_socket, &ev);
+       if (ret)
+               goto err_close_epoll;
+#endif
+
+       port_desc->proto = &proto_inet;
+       port_desc->proto_priv = port_priv;
+       port_desc->addr = &port_priv->addr;
+       return 0;
+err_close_epoll:
+       close(port_priv->epoll_fd);
+err_close_listen:
+       ret = errno;
+       close(port_priv->listen_socket);
+       errno = ret;
+err_close_udp:
+       ret = errno;
+       close(port_priv->udp_socket);
+       errno = ret;
+err_free:
+       ret = errno;
+       forb_free(port_priv);
+       errno = ret;
+       return -1;
+}
diff --git a/src/forb/src/proto_inet.h b/src/forb/src/proto_inet.h
new file mode 100644 (file)
index 0000000..ad3a048
--- /dev/null
@@ -0,0 +1,66 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/** 
+ * 
+ * @file   proto_inet.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 19:03:10 2008
+ * 
+ * @brief  Prototypes for INET transport protocol
+ */
+
+#ifndef FORB_PROTO_INET_H
+#define FORB_PROTO_INET_H
+
+#include <forb/port.h>
+#include <netinet/in.h>
+#include <stdint.h>
+
+int forb_inet_port_init(struct forb_port_desc *port_desc, struct in_addr listen_on,
+                       uint16_t port);
+
+#endif
diff --git a/src/forb/src/proto_unix.c b/src/forb/src/proto_unix.c
new file mode 100644 (file)
index 0000000..a49a9a6
--- /dev/null
@@ -0,0 +1,231 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+#include <dirent.h>
+#include "proto.h"
+#include <forb/proto_unix.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+
+/**
+ * @file   proto_unix.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:10:23 2008
+ * 
+ * @brief  FORB transport protocol based on UNIX DGRAM sockets.
+ * 
+ * The sockets are created in filesystem in #FORB_TMP_DIR directory.
+ */
+
+
+typedef struct sockaddr_un unix_addr_t;
+
+/** UNIX protocol data for ports. */
+struct unix_port {
+       int socket;
+       unix_addr_t addr;
+};
+
+static struct unix_port*
+peer_to_uport(forb_peer_t *peer) { return peer->port->desc.proto_priv; }
+
+static void
+unix_server_to_addr(unix_addr_t *addr, const forb_server_id *server)
+{
+       char str[65];
+       addr->sun_family = AF_UNIX;
+       sprintf(addr->sun_path, FORB_TMP_DIR "/sock.%s",
+               forb_uuid_to_string(str, (forb_uuid_t*)server->uuid, sizeof(str)));
+}
+
+static ssize_t
+unix_send(forb_peer_t *peer, const void *buf, size_t len)
+{
+       unix_addr_t addr;
+       struct unix_port *p = peer_to_uport(peer);
+       //printf("send to %s\n", c->addr.sun_path);
+        unix_server_to_addr(&addr, &peer->server_id);
+       return sendto(p->socket, buf, len, 0,
+                     (struct sockaddr*)&addr, sizeof(addr));
+}
+
+static ssize_t
+unix_recv(forb_port_t *port, void *buf, size_t len)
+{
+       struct unix_port *p = port->desc.proto_priv;
+       return recv(p->socket, buf, len, 0);
+}
+
+static int
+unix_port_destroy(forb_port_t * port)
+{
+       struct unix_port *pd = port->desc.proto_priv;
+       unix_addr_t addr;
+       socklen_t len = sizeof(addr);
+       getsockname(pd->socket, (struct sockaddr*)&addr, &len);
+       if (addr.sun_family == AF_UNIX)
+               unlink(addr.sun_path);
+       close(pd->socket);
+       forb_free(pd);
+       return 0;
+}
+
+static ssize_t
+unix_broadcast(forb_port_t *port, const void *buf, size_t len)
+{
+       struct unix_port *p = port->desc.proto_priv;
+       DIR *dir;
+       struct dirent *dirent;
+       unix_addr_t addr;
+       int ret;
+       int success = 0;
+       
+       dir = opendir(FORB_TMP_DIR);
+       if (!dir) return -errno;
+
+       addr.sun_family = AF_UNIX;
+       
+       while ((dirent = readdir(dir))) {
+               bool forb_socket = 
+#ifdef _DIRENT_HAVE_D_TYPE
+                       (dirent->d_type == DT_SOCK ||
+                        dirent->d_type == DT_UNKNOWN) &&
+#else
+#warning This system does not support _DIRENT_HAVE_D_TYPE
+#endif
+                       (strncmp(dirent->d_name, "sock.", 5) == 0);
+               
+/*             printf("d_name=%s d_type=%d (%d)\n", dirent->d_name, dirent->d_type, DT_SOCK); */
+               if (forb_socket)
+               {
+                       strcpy(addr.sun_path, FORB_TMP_DIR "/");
+                       strncat(addr.sun_path, dirent->d_name, sizeof(addr.sun_path));
+/*                     printf("Broadcasting to %s\n", addr.sun_path); */
+                       ret = sendto(p->socket, buf, len, 0,
+                                    (struct sockaddr*)&addr, sizeof(addr));
+                       /* We do not care about errors in brodcasts -
+                        * the socket may nomore be active */
+                       if (ret == len) {
+                               success++;
+                       } else if (ret < 0 && errno == ECONNREFUSED) {
+                               /* Try to unlink stale socket */
+                               unlink(addr.sun_path);
+                       } else {
+/*                             perror("unix_broadcast"); */
+/*                             return ret; */
+                       }
+               }
+                       
+       }
+       closedir(dir);
+       if (success) {
+               ret = len;
+       } else {
+               ret = -1;
+       }
+       return ret;
+}
+
+static const forb_proto_t proto_unix = {
+       .hello_interval = 40 /* seconds */,
+       .port_destroy = unix_port_destroy,
+       .peer_destroy = NULL,
+       .send = unix_send,
+       .recv = unix_recv,
+       .broadcast = unix_broadcast,
+       /* We do not need the following functions, sice the address
+        * can be derived from server_id */
+       .serialize_addr = NULL,
+       .deserialize_addr = NULL,
+};
+
+/** 
+ * Initializes UNIX protocol port.
+ * 
+ * @param port Port to initialize.
+ * @param server Server this port belongs to.
+ * 
+ * @return Zero on success, -1 on error and errno is set
+ * appropriately.
+ */
+int
+forb_unix_port_init(struct forb_port_desc *port_desc, const forb_server_id *server)
+{
+       
+       int ret;       
+       struct unix_port *pd;
+
+       ret = forb_init_tmp_dir();
+
+       pd = forb_malloc(sizeof(*pd));
+       if (!pd)
+               return -1;
+       
+       pd->socket = socket(PF_UNIX, SOCK_DGRAM, 0);
+       if (pd->socket == -1) goto err1;
+
+       unix_server_to_addr(&pd->addr, server);
+       /* unlink(pd->addr.sun_path); */ /* TODO: What to do when the socket already exist? */
+       ret = bind(pd->socket, (struct sockaddr*)&pd->addr, sizeof(pd->addr));
+       chmod(pd->addr.sun_path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+       if (ret == -1) goto err;
+
+       port_desc->proto = &proto_unix;
+       port_desc->proto_priv = pd;
+       return 0;
+err:
+       ret = errno;
+       close(pd->socket);
+       errno = ret;
+err1:
+       ret = errno;
+       forb_free(pd);
+       errno = ret;
+       return -1;
+}
diff --git a/src/forb/src/proto_unix.h b/src/forb/src/proto_unix.h
new file mode 100644 (file)
index 0000000..fb44b32
--- /dev/null
@@ -0,0 +1,62 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/** 
+ * 
+ * @file   proto_unix.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 19:03:10 2008
+ * 
+ * @brief  Prototypes for UNIX transport protocol
+ */
+
+#ifndef FORB_PROTO_UNIX_H
+#define FORB_PROTO_UNIX_H
+
+int forb_unix_port_init(struct forb_port_desc *port_desc,
+                       const forb_server_id *server);
+
+#endif
diff --git a/src/forb/src/refcnt.c b/src/forb/src/refcnt.c
new file mode 100644 (file)
index 0000000..9c76737
--- /dev/null
@@ -0,0 +1,103 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   refcnt.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Wed Oct  1 09:23:40 2008
+ * 
+ * @brief  Atomic reference counting operations.
+ *
+ * @note To provide portable atomicity, we use GCC's builtin
+ * functions introduced in GCC 4.1.
+ * 
+ */
+#include "refcnt.h"
+
+void forb_ref_set(struct forb_ref *ref, int num)
+{
+       ref->refcount = num;
+}
+
+/** 
+ * Initializes reference count to 1.
+ * 
+ * @param ref 
+ */
+void forb_ref_init(struct forb_ref *ref)
+{
+       forb_ref_set(ref, 1);
+}
+
+/** 
+ * Atomicaly increases reference count
+ * 
+ * @param ref 
+ */
+void forb_ref_get(struct forb_ref *ref)
+{
+       __sync_add_and_fetch(&ref->refcount, 1);
+}
+
+/** 
+ * Atomicaly decreases reference count and if zero is reached calls, @a
+ * release function (destructor).
+ * 
+ * @param ref Reference to act on.
+ * @param release Release function called when reference count reaches zero.
+ * 
+ * @return 1 if the @a release function was called, zero othewise
+ * (which doesn't mean that the object still exist in memory as it
+ * might be released by somebody else in the mean time).
+ */
+int forb_ref_put(struct forb_ref *ref, void (*release) (struct forb_ref *ref))
+{
+       if (__sync_add_and_fetch(&ref->refcount, -1) == 0) {
+               release(ref);
+               return 1;
+       }
+       return 0;
+}
diff --git a/src/forb/src/refcnt.h b/src/forb/src/refcnt.h
new file mode 100644 (file)
index 0000000..cd6a314
--- /dev/null
@@ -0,0 +1,77 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+#ifndef FORB_REFCNT_H
+#define FORB_REFCNT_H
+
+/**
+ * @file   refcnt.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 16:03:51 2008
+ * 
+ * @brief  Atomic reference counting types and prototypes. 
+ * 
+ * 
+ */
+
+
+/**
+ * Reference counter type
+ * 
+ */
+struct forb_ref {
+       unsigned refcount;
+};
+
+typedef struct forb_ref forb_ref_t;
+
+void forb_ref_set(struct forb_ref *ref, int num);
+void forb_ref_init(struct forb_ref *ref);
+void forb_ref_get(struct forb_ref *ref);
+int forb_ref_put(struct forb_ref *ref, void (*release) (struct forb_ref *ref));
+       
+
+#endif
diff --git a/src/forb/src/regref.c b/src/forb/src/regref.c
new file mode 100644 (file)
index 0000000..1d6f62c
--- /dev/null
@@ -0,0 +1,366 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+#include "regref.h"
+#include "object.h"
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ul_log.h>
+#include <forb/config.h>
+
+extern UL_LOG_CUST(ulogd_forb_regref);
+
+static inline int forb_regref_cmp(const forb_regref_name_t *a, const forb_regref_name_t *b)
+{
+       return strncmp(a->str, b->str, FORB_REGREF_NAME_LEN);
+}
+
+GAVL_CUST_NODE_INT_IMP(forb_regref_nolock /* cust_prefix */,
+                      forb_t /* cust_root_t */,
+                      forb_regref_t /* cust_item_t */,
+                      forb_regref_name_t /* cust_key_t */,
+                      regrefs /* cust_root_node */,
+                      node /* cust_item_node */,
+                      name /* cust_item_key */,
+                      forb_regref_cmp/* cust_cmp_fnc */);
+
+/** 
+ * Allocates a new ::forb_regref_t structure and fills it with data.
+ * 
+ * @param object Object reference to register.
+ * 
+ * @param name Name of the registered object reference, which can be
+ * used by other applications in forb_resolve_reference().
+ * 
+ * @return Pointer to the newly allocated regref of NULL in case of error.
+ */
+forb_regref_t *
+forb_regref_new(forb_object object, forb_regref_name_t name)
+{
+       forb_regref_t *regref;
+
+       regref = forb_malloc(sizeof(*regref));
+       if (regref) {
+               regref->name = name;
+               regref->object = forb_object_duplicate(object);
+       }
+       return regref;
+}
+
+/** 
+ * Releases ::forb_regref_t previously allocated by forb_regref_new().
+ * 
+ * @param regref Regref to release.
+ */
+void 
+forb_regref_release(forb_regref_t *regref)
+{
+       if (regref) {
+               forb_object_release(regref->object);
+               forb_free(regref);
+       }
+}
+
+
+
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+/** 
+ * 
+ * 
+ * @param fd 
+ * @param objref 
+ * 
+ * @return Zero on success, -1 on error.
+ */
+static int
+rewrite_regref(int fd, const char *objref)
+{
+       int ret;
+       int len = strlen(objref);
+       lseek(fd, 0, SEEK_SET);
+       ftruncate(fd, 0);
+               
+       while (len > 0) {
+               ret = write(fd, objref, len);
+               if (ret < 0) goto out;
+               len -= ret;
+               objref += ret;
+       }
+       ret = 0;        /* Success */
+out:
+       return ret;
+}
+
+/** 
+ * 
+ * 
+ * @param orb 
+ * @param fn File name
+ * @param objref string form of the object reference
+ * 
+ * @return -1 on error, 0 if reference was replaced and 1 in the
+ * reference is valid.
+ */
+static int
+replace_regref_if_stale(forb_orb orb, const char *fn, const char *objref)
+{
+       int fd, ret = 0; 
+       char str[100];
+       forb_object object;
+       
+       fd = open(fn, O_RDWR);
+       if (fd < 0) {
+               ret = -1;
+               goto out;
+       }
+       ret = lockf(fd, F_LOCK, 0);
+       if (ret < 0) goto close_err;
+       ret = read(fd, str, sizeof(str)-1);
+       if (ret < 0) goto unlock_err;
+       /* TODO: Check that we have read the whole file */
+       
+       str[ret] = '\0';
+       object = forb_string_to_object(orb, str);
+       if (!object) {
+               /* reference is unreadable, so we can replace it */
+               ret = rewrite_regref(fd, objref);
+               /* We are done for now */
+               goto unlock_err;
+       }
+       if (forb_object_is_stale(object)) {
+               /* Orb is not alive */
+               ret = rewrite_regref(fd, objref);
+       } else {
+               /* Reference's FORB is alive :-( */
+               ret = 1;        
+       }
+
+       forb_object_release(object);
+unlock_err:    
+       lockf(fd, F_ULOCK, 0);
+close_err:
+       close(fd);
+out:
+       return ret;
+}
+#endif
+
+/** 
+ * Registers a given object reference so that other FORBs on the same
+ * node can find it by using forb_resolve_reference().
+ * 
+ * @param object Object reference to register.
+ * @param name Name under which to register the reference.
+ *
+ * @return Zero on success, -1 on error.
+ */
+int
+forb_register_reference(forb_object object, const char *name)
+{
+       forb_regref_t *regref;
+       forb_regref_name_t regname;
+       forb_t *forb = forb_object_to_forb(object);
+
+       strncpy(regname.str, name, FORB_REGREF_NAME_LEN-1);
+       regname.str[FORB_REGREF_NAME_LEN-1]='\0';
+
+       regref = forb_regref_new(object, regname);
+       if (!regref) goto err;
+
+       forb_regref_insert(forb, regref);
+
+#ifdef CONFIG_FORB_PROTO_INET_DEFAULT
+       return 0;
+#else
+       char fn[100], fntmp[100];
+       char *objref;
+       FILE *f;
+       int ret;
+       snprintf(fn,    sizeof(fn),    FORB_TMP_DIR "/%s",    regname.str);
+       snprintf(fntmp, sizeof(fntmp), FORB_TMP_DIR "/%s.%s", regname.str,
+                forb->server_id_str);
+
+       f = fopen(fntmp, "w");
+       if (!f) goto unalloc_err;
+       
+       objref = forb_object_to_string(object);
+       if (!objref) goto unlink_err;
+
+       ret = fprintf(f, "%s", objref);
+       if (ret < 0) goto free_objref_err;
+
+       ret = fclose(f);
+       if (ret == EOF) goto free_objref_err;
+
+       /* Make the atomic registration in filesystem */
+       ret = link(fntmp, fn);
+       
+       if (ret < 0 && errno == EEXIST) {
+               /* The reference exists. Try whether it is still
+                * active. */
+               if (replace_regref_if_stale(object->orb, fn, objref) != 0) {
+                       goto free_objref_err;
+               }
+               ul_logdeb("Stale registration replaced\n");
+       } else if (ret < 0) {
+               goto free_objref_err;
+       }
+
+       forb_free(objref);
+
+       /* Unlink the temporary filename */
+       unlink(fntmp);
+       
+       return 0;
+free_objref_err:
+       ret = errno;
+       forb_free(objref);
+       errno = ret;
+unlink_err:
+       ret = errno;
+       unlink(fntmp);
+       errno = ret;
+unalloc_err:
+       ret = errno;
+       forb_regref_delete(forb, regref);
+       forb_regref_release(regref);
+       errno = ret;
+#endif
+err:
+       return -1;
+}
+
+/** 
+ * Unregister reference previously registered by
+ * forb_register_reference().
+ * 
+ * @param orb forb::orb reference
+ * @param name Name to unregister.
+ * 
+ * @return Zero on success, -1 on error.
+ */
+int
+forb_unregister_reference(forb_orb orb, const char *name)
+{
+       forb_regref_t *regref;
+       forb_regref_name_t regname;
+       forb_t *forb = forb_object_to_forb(orb);
+
+       strncpy(regname.str, name, FORB_REGREF_NAME_LEN-1);
+       regname.str[FORB_REGREF_NAME_LEN-1]='\0';
+
+       regref = forb_regref_find(forb, &regname);
+       if (!regref) goto err;
+
+       forb_regref_delete(forb, regref);
+       forb_regref_release(regref);
+
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+       char fn[100];
+       snprintf(fn,    sizeof(fn),    FORB_TMP_DIR "/%s",    regname.str);
+       return unlink(fn);
+#endif
+
+       return 0;
+err:
+       return -1;
+}
+
+/** 
+ * Returns a named reference previously registered by
+ * forb_register_reference(). This function can be called even if the
+ * reference was registered in a diferent process (but on the same
+ * node).
+ * 
+ * @param orb Local orb object reference
+ * @param name Name under which the reference was registered.
+ * 
+ * @return Object reference on NULL in case of error.
+ */
+forb_object
+forb_resolve_reference(const forb_orb orb, const char *name)
+{
+       forb_regref_name_t regname;
+       forb_object object;
+
+       strncpy(regname.str, name, FORB_REGREF_NAME_LEN-1);
+       regname.str[FORB_REGREF_NAME_LEN-1]='\0';
+
+#ifdef CONFIG_FORB_PROTO_INET_DEFAULT
+       forb_regref_t *regref;
+       forb_t *forb = forb_object_to_forb(orb);
+
+       regref = forb_regref_find(forb, &regname);
+       if (!regref) return NULL;
+
+       object = forb_object_duplicate(regref->object);
+       return object;
+
+#else
+       char fn[100];
+       char str[100];
+       int fd, ret;
+
+       snprintf(fn,    sizeof(fn),    FORB_TMP_DIR "/%s",    regname.str);
+
+       fd = open(fn, 0);
+       if (fd < 0) {
+               return NULL;
+       }
+       ret = read(fd, str, sizeof(str)-1);
+       /* TODO: Check that we have read the whole file */
+       str[ret] = '\0';
+       object = forb_string_to_object(orb, str);
+       close(fd);
+#endif
+
+       if (forb_object_is_stale(object)) {
+               forb_object_release(object);
+               object = NULL;
+       }
+       return object;
+}
diff --git a/src/forb/src/regref.h b/src/forb/src/regref.h
new file mode 100644 (file)
index 0000000..1ec9c54
--- /dev/null
@@ -0,0 +1,137 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   regref.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sat Oct 11 14:46:08 2008
+ * 
+ * @brief Handling of registered object references.
+ * 
+ * 
+ */
+
+#ifndef FORB_REGREF_H
+#define FORB_REGREF_H
+
+#include <forb.h>
+#include <forb/forb-internal.h>
+#include <ul_gavl.h>
+
+#define FORB_REGREF_NAME_LEN 32
+
+/**
+ * Type for registered names
+ *
+ * We must encapsulate the array in structure in order to behave as
+ * normal C object. This is necessary for usage as GAVL key. The
+ * reason is that typeof(&array) == typeof(array).
+ */
+typedef struct {
+       char str[FORB_REGREF_NAME_LEN];
+} forb_regref_name_t;
+
+struct forb_regref {
+       forb_regref_name_t name; /**< Name of the registered reference */
+       forb_object object;      /**< Registered object reference */
+       gavl_node_t node;        /**< Node for forb->regrefs tree */
+};
+
+typedef struct forb_regref forb_regref_t;
+
+GAVL_CUST_NODE_INT_DEC(forb_regref_nolock /* cust_prefix */,
+                      forb_t /* cust_root_t */,
+                      forb_regref_t /* cust_item_t */,
+                      forb_regref_name_t /* cust_key_t */,
+                      regrefs /* cust_root_node */,
+                      node /* cust_item_node */,
+                      name /* cust_item_key */,
+                      forb_regref_cmp/* cust_cmp_fnc */);
+
+
+forb_regref_t *
+forb_regref_new(forb_object object, forb_regref_name_t name);
+
+void 
+forb_regref_release(forb_regref_t *regref);
+
+static inline void
+forb_regref_insert(forb_t *forb, forb_regref_t *regref)
+{
+       pthread_mutex_lock(&forb->regref_mutex);
+       forb_regref_nolock_insert(forb, regref);
+       pthread_mutex_unlock(&forb->regref_mutex);
+}
+
+static inline void
+forb_regref_delete(forb_t *forb, forb_regref_t *regref)
+{
+       pthread_mutex_lock(&forb->regref_mutex);
+       forb_regref_nolock_delete(forb, regref);
+       pthread_mutex_unlock(&forb->regref_mutex);
+}
+
+static inline forb_regref_t *
+forb_regref_find(forb_t *forb, forb_regref_name_t const *name)
+{
+       forb_regref_t *regref;
+       pthread_mutex_lock(&forb->regref_mutex);
+       regref = forb_regref_nolock_find(forb, name);
+       pthread_mutex_unlock(&forb->regref_mutex);
+       return regref;
+}
+
+static inline forb_regref_t *
+forb_regref_first(forb_t *forb)
+{
+       forb_regref_t *regref;
+       pthread_mutex_lock(&forb->regref_mutex);
+       regref = forb_regref_nolock_first(forb);
+       pthread_mutex_unlock(&forb->regref_mutex);
+       return regref;
+}
+
+#endif
diff --git a/src/forb/src/request.c b/src/forb/src/request.c
new file mode 100644 (file)
index 0000000..b6b1196
--- /dev/null
@@ -0,0 +1,162 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   request.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 19:04:21 2008
+ * 
+ * @brief  Implementation of request handling functions
+ * 
+ * 
+ */
+
+#include <forb/forb-internal.h>
+#include "request.h"
+#include <forb/iop-idl.h>
+#include <forb/object.h>
+#include "peer.h"
+#include "iop.h"
+#include "proto.h"
+#include <ul_log.h>
+
+extern UL_LOG_CUST(ulogd_forb_request);
+
+static inline int forb_request_cmp(const CORBA_unsigned_long *a,
+                                  const CORBA_unsigned_long *b)
+{
+       return (*a<*b) ? -1 :
+               ((*a>*b) ? +1 :
+                0);
+}
+
+GAVL_CUST_NODE_INT_IMP(forb_request_nolock /* cust_prefix */,
+                      forb_t /* cust_root_t */,
+                      forb_request_t /* cust_item_t */,
+                      CORBA_unsigned_long /* cust_key_t */,
+                      requests /* cust_root_node */,
+                      node /* cust_item_node */,
+                      request_id /* cust_item_key */,
+                      forb_request_cmp/* cust_cmp_fnc */);
+
+/** 
+ * Initializes @a req structure for sending new request to object @a obj.
+ * 
+ * @param req Request structure to initialize
+ * @param obj Destination object
+ *
+ * @return Zero on success, FOSA error code on error.
+ */
+int
+forb_request_init(forb_request_t *req, forb_object obj)
+{
+       int ret = 0;
+       forb_t *forb = forb_object_to_forb(obj);
+       CORBA_boolean bret;
+
+       memset(req, 0, sizeof(*req));
+       req->obj = obj;
+
+       fosa_mutex_lock(&forb->request_id_mutex);
+       req->request_id = forb->request_id++;
+       fosa_mutex_unlock(&forb->request_id_mutex);
+
+       FORB_CDR_codec_init_static(&req->cdr_request, obj->orb);
+       bret = FORB_CDR_buffer_init(&req->cdr_request, 4096-8, forb_iop_MESSAGE_HEADER_SIZE);
+       if (bret == CORBA_FALSE) {
+               return FOSA_ENOMEM;
+       }
+       
+       ret = forb_syncobj_init(&req->reply_ready, 0);
+       return ret;
+}
+
+void
+forb_request_destroy(forb_request_t *req)
+{
+       forb_t *forb = forb_object_to_forb(req->obj);
+
+       forb_request_delete(forb, req);
+       FORB_CDR_codec_release_buffer(&req->cdr_request);
+       forb_syncobj_destroy(&req->reply_ready);
+}
+
+void
+forb_request_signal_reply(forb_request_t *req)
+{
+       forb_syncobj_signal(&req->reply_ready); 
+}
+
+void
+forb_request_wait_for_reply(forb_request_t *req)
+{
+       fosa_abs_time_t timeout;
+       int ret;
+
+       /* FIXME: What is the appropriate length for timeout? Maybe,
+        * we can specify timeout in forb_env, but since it is
+        * out-direction parameter, we cannot distinguish between
+        * initialized and uninitialized env.timeout.  */
+       fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &timeout);
+       timeout = fosa_abs_time_incr(timeout,
+                                    fosa_msec_to_rel_time(10000));
+
+       ret = forb_syncobj_timedwait(&req->reply_ready, &timeout);
+
+       if (ret == ETIMEDOUT) {
+               req->env->major = FORB_EX_TIMEOUT;
+       } else if (ret) {
+               req->env->major = FORB_EX_INTERNAL;
+       }
+}
+
+void
+forb_request_signal_processed(forb_request_t *req)
+{
+       /* Signal, that we are done */
+       forb_syncobj_signal(req->reply_processed);
+}
+
diff --git a/src/forb/src/request.h b/src/forb/src/request.h
new file mode 100644 (file)
index 0000000..1b1d0fc
--- /dev/null
@@ -0,0 +1,138 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+#ifndef REQUEST_H
+#define REQUEST_H
+
+/**
+ * @file   request.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 15:50:30 2008
+ * 
+ * @brief  Data type and functions for manipulation with requests.
+ * 
+ * 
+ */
+
+
+#include <forb.h>
+#include <forb/cdr.h>
+#include <forb/basic_types.h>
+#include <forb/syncobj.h>
+#include <ul_gavlcust.h>
+#include <forb/forb-internal.h>
+
+
+
+/**
+ * Helper structure for sending ORB requests.
+ *
+ * Its purpose is to match incomming reply messages to previously sent
+ * requests. It is allocated in stub's stack and during waiting for
+ * reply is stored in forb_t::requests tree.
+ * 
+ */
+struct forb_request {
+       CORBA_unsigned_long request_id; /**< Numeric ID of this request. Used to match replies agains this request. */
+       FORB_CDR_Codec cdr_request;     /**< Buffer for the request serialization. */
+       FORB_CDR_Codec *cdr_reply;      /**< Buffer with received reply. */
+       gavl_node_t node;       /**< forb_t::requests node */
+       forb_object obj;        /**< Object being requested. */
+       struct forb_env *env;   /**< Where to store exception returned in reply */
+       forb_syncobj_t reply_ready; /**< Synchronization object for waiting for reply */
+       forb_syncobj_t *reply_processed; /**< Synchronization object for receiver thread to wait for stub. */
+};
+
+typedef struct forb_request forb_request_t;
+
+/* Declaration of AVL tree for storing sent requests. */
+GAVL_CUST_NODE_INT_DEC(forb_request_nolock /* cust_prefix */,
+                      forb_t /* cust_root_t */,
+                      forb_request_t /* cust_item_t */,
+                      CORBA_unsigned_long /* cust_key_t */,
+                      requests /* cust_root_node */,
+                      node /* cust_item_node */,
+                      request_id /* cust_item_key */,
+                      forb_request_cmp/* cust_cmp_fnc */);
+
+static inline int
+forb_request_insert(forb_t *forb, forb_request_t *req)
+{
+       int ret;
+       fosa_mutex_lock(&forb->request_mutex);
+       ret = forb_request_nolock_insert(forb, req);
+       fosa_mutex_unlock(&forb->request_mutex);
+       return ret;
+}
+
+static inline void
+forb_request_delete(forb_t *forb, forb_request_t *req)
+{
+       fosa_mutex_lock(&forb->request_mutex);
+       forb_request_nolock_delete(forb, req);
+       fosa_mutex_unlock(&forb->request_mutex);
+}
+
+static inline forb_request_t *
+forb_request_find(forb_t *forb, CORBA_unsigned_long *request_id)
+{
+       forb_request_t *ret;
+       fosa_mutex_lock(&forb->request_mutex);
+       ret = forb_request_nolock_find(forb, request_id);
+       fosa_mutex_unlock(&forb->request_mutex);
+       return ret;
+}
+
+int
+forb_request_init(forb_request_t *req, forb_object obj);
+void
+forb_request_destroy(forb_request_t *req);
+void
+forb_request_wait_for_reply(forb_request_t *req);
+void
+forb_request_signal_processed(forb_request_t *req);
+
+#endif
diff --git a/src/forb/src/server_id.h b/src/forb/src/server_id.h
new file mode 100644 (file)
index 0000000..17effdc
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef FORB_SERVER_ID_H
+#define FORB_SERVER_ID_H
+
+#include <forb/uuid.h>
+#include <forb/types.h>
+
+void
+forb_server_id_init(forb_server_id *serer);
+
+/** 
+ * Compares to server IDs.
+ * 
+ * @param id1 
+ * @param id2 
+ * 
+ * @return -1, 0 or 1 if the @a id1 is less, equal on greated to @a id2 respectively.
+ */
+static inline int forb_server_id_cmp(const forb_server_id *id1, const forb_server_id *id2)
+{
+       return memcmp(id1, id2, sizeof(forb_server_id));
+}
+
+/** 
+ * Converts a server ID to string.
+ * 
+ * @param dest Where to store the converted string.
+ * @param server_id Server ID to convert.
+ * @param n The size of @a dest memory buffer.
+ * 
+ * @return Same value as @a dest.
+ */
+static inline char *
+forb_server_id_to_string(char *dest, const forb_server_id *server_id, size_t n)
+{
+       return forb_uuid_to_string(dest, (forb_uuid_t*)server_id->uuid, n);
+}
+
+/** 
+ * Initializes server ID from string.
+ * 
+ * @param server_id Initialized server ID.
+ * @param string String form of server ID.
+ * 
+ * @return Same value as @a server_id.
+ */
+static inline forb_server_id * 
+forb_server_id_from_string(forb_server_id *server_id, const char *string)
+{
+       return (forb_server_id *)forb_uuid_from_string((forb_uuid_t*)&server_id->uuid, string);
+}
+
+
+static inline bool
+forb_server_id_empty(const forb_server_id *server_id)
+{
+       unsigned i;
+       for (i=0; i<sizeof(server_id); i++) {
+               if (server_id->uuid[i] != 0)
+                       return false;
+       }
+       return true;
+}
+
+#endif
diff --git a/src/forb/src/sha1.c b/src/forb/src/sha1.c
new file mode 100644 (file)
index 0000000..a490d26
--- /dev/null
@@ -0,0 +1,269 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+/* #define LITTLE_ENDIAN * This should be #define'd if true. */
+/* #define SHA1HANDSOFF * Copies data before messing with it. */
+
+/* #include <stdio.h> */
+#include <inttypes.h>
+#include <string.h>
+#include "sha1.h"
+
+/* Extract endinaning from glibc */
+#include <endian.h>
+#undef LITTLE_ENDIAN
+#ifdef __BYTE_ORDER
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define LITTLE_ENDIAN
+#endif
+#endif
+
+void SHA1Transform(uint32_t state[5], uint8_t buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, uint8_t* data, unsigned int len);
+void SHA1Final(uint8_t digest[20], SHA1_CTX* context);
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifdef LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(uint32_t state[5], uint8_t buffer[64])
+{
+uint32_t a, b, c, d, e;
+typedef union {
+    uint8_t c[64];
+    uint32_t l[16];
+} CHAR64LONG16;
+CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+static uint8_t workspace[64];
+    block = (CHAR64LONG16*)workspace;
+    memcpy(block, buffer, 64);
+#else
+    block = (CHAR64LONG16*)buffer;
+#endif
+    /* Copy context->state[] to working vars */
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+    /* Add the working vars back into context.state[] */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+    /* Wipe variables */
+    a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX* context)
+{
+    /* SHA1 initialization constants */
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+    context->state[4] = 0xC3D2E1F0;
+    context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX* context, uint8_t* data, unsigned int len)
+{
+unsigned int i, j;
+
+    j = (context->count[0] >> 3) & 63;
+    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
+    context->count[1] += (len >> 29);
+    if ((j + len) > 63) {
+        memcpy(&context->buffer[j], data, (i = 64-j));
+        SHA1Transform(context->state, context->buffer);
+        for ( ; i + 63 < len; i += 64) {
+            SHA1Transform(context->state, &data[i]);
+        }
+        j = 0;
+    }
+    else i = 0;
+    memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(uint8_t digest[20], SHA1_CTX* context)
+{
+unsigned long i, j;
+uint8_t finalcount[8];
+
+    for (i = 0; i < 8; i++) {
+        finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)]
+         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
+    }
+    SHA1Update(context, (uint8_t *)"\200", 1);
+    while ((context->count[0] & 504) != 448) {
+        SHA1Update(context, (uint8_t *)"\0", 1);
+    }
+    SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
+    for (i = 0; i < 20; i++) {
+        digest[i] = (uint8_t)
+         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+    }
+    /* Wipe variables */
+    i = j = 0;
+    memset(context->buffer, 0, 64);
+    memset(context->state, 0, 20);
+    memset(context->count, 0, 8);
+    memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
+    SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+
+/*************************************************************/
+
+#if 0
+#include <stdio.h>
+
+int main(int argc, char** argv)
+{
+int i, j;
+SHA1_CTX context;
+uint8_t digest[20], buffer[16384];
+FILE* file;
+
+    if (argc > 2) {
+        puts("Public domain SHA-1 implementation - by Steve Reid <steve@edmweb.com>");
+        puts("Produces the SHA-1 hash of a file, or stdin if no file is specified.");
+        exit(0);
+    }
+    if (argc < 2) {
+        file = stdin;
+    }
+    else {
+        if (!(file = fopen(argv[1], "rb"))) {
+            fputs("Unable to open file.", stderr);
+            exit(-1);
+        }
+    } 
+    SHA1Init(&context);
+    while (!feof(file)) {  /* note: what if ferror(file) */
+        i = fread(buffer, 1, 16384, file);
+        SHA1Update(&context, buffer, i);
+    }
+    SHA1Final(digest, &context);
+    fclose(file);
+    for (i = 0; i < 5; i++) {
+        for (j = 0; j < 4; j++) {
+            printf("%02X", digest[i*4+j]);
+        }
+        putchar(' ');
+    }
+    putchar('\n');
+    exit(0);
+}
+#endif
diff --git a/src/forb/src/sha1.h b/src/forb/src/sha1.h
new file mode 100644 (file)
index 0000000..e76f3dc
--- /dev/null
@@ -0,0 +1,64 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+*/
+
+#include <inttypes.h>
+
+typedef struct {
+    unsigned long count[2];
+    uint32_t state[5];
+    uint8_t buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform(uint32_t state[5], uint8_t buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, uint8_t* data, unsigned int len);
+void SHA1Final(uint8_t digest[20], SHA1_CTX* context);
diff --git a/src/forb/src/syncobj.c b/src/forb/src/syncobj.c
new file mode 100644 (file)
index 0000000..7efb289
--- /dev/null
@@ -0,0 +1,202 @@
+//----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politecnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org
+//
+//        The FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+// This file is part of DTM (Distributed Transaction Manager)
+//
+// DTM is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version.  DTM is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with DTM; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including DTM header files in a file,
+// instantiating DTM generics or templates, or linking other files
+// with DTM objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/**
+ * @file 
+ *
+ * @brief Synchronization object used in FORB
+ *
+ * @author
+ *      Michael Gonzalez Harbour <mgh@unican.es>
+ *      Michal Sojka <sojkam1@fel.cvut.cz>
+ *      Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @comments
+ *
+ * This module contains the definition of the data object and operations to
+ * create a pool of objects, obtain the id of an unused object, wait upon it,
+ * signal it, and finish using it.
+ *
+ * @license
+ *
+ * See the COPYING file in the FORB's root directory
+ *
+ */
+
+#include "syncobj.h"
+
+/**
+ * Initializes the synchronization object.
+ *
+ * @return Zero on success, FOSA error code on error.
+ **/
+
+int forb_syncobj_init(forb_syncobj_t *syncobj, int ceiling)
+{
+        int err;
+
+       err = fosa_cond_init(&syncobj->cond);
+        if (err != 0) return err;
+
+        syncobj->is_work_done = false;
+
+        err = fosa_mutex_init(&syncobj->mutex, ceiling);
+        if (err != 0) return err;
+
+        return 0;
+}
+
+/**
+ * Destroys all resources related to the synchronization object.
+ **/
+
+int forb_syncobj_destroy(forb_syncobj_t *syncobj)
+{
+        int err;
+
+       err = fosa_cond_destroy(&syncobj->cond);
+       if (err != 0) return err;
+       
+       err = fosa_mutex_destroy(&syncobj->mutex);
+       if (err != 0) return err;
+
+        return 0;
+}
+
+/**
+ * Signal the synchronization object.
+ **/
+
+int forb_syncobj_signal(forb_syncobj_t *syncobj)
+{
+        int err;
+
+        err = fosa_mutex_lock(&syncobj->mutex);
+        if (err != 0) return err;
+
+       syncobj->is_work_done = true;
+
+       err = fosa_cond_signal(&syncobj->cond);
+       if (err != 0) goto locked_error;
+
+        err = fosa_mutex_unlock(&syncobj->mutex);
+        if (err != 0) return err;
+
+        return 0;
+
+locked_error:
+        fosa_mutex_unlock(&syncobj->mutex);
+        return err;
+}
+
+static void
+syncobj_cleanup(void *syncobj)
+{
+       forb_syncobj_t *s = syncobj;
+       fosa_mutex_unlock(&s->mutex);
+}
+
+/**
+ * Wait on the synchronization object.
+ **/
+
+int forb_syncobj_wait(forb_syncobj_t *syncobj)
+{
+        int err = 0;
+
+        err = fosa_mutex_lock(&syncobj->mutex);
+        if (err != 0) return err;
+       pthread_cleanup_push(syncobj_cleanup, syncobj);
+
+       while (syncobj->is_work_done == false) {
+               err = fosa_cond_wait(&syncobj->cond,
+                                    &syncobj->mutex);
+               if (err != 0) goto locked_error;
+       }
+       
+       syncobj->is_work_done = false;
+
+locked_error:;
+       pthread_cleanup_pop(1);
+        return err;
+;
+}
+
+/**
+ * Wait on the synchronization object with a timeout.
+ *
+ * @return Zero on success, ETIMEDOUT on timeout or other FOSA error
+ * code on error.
+ **/
+
+int forb_syncobj_timedwait(forb_syncobj_t *syncobj,
+                          const struct timespec *abstime)
+{
+        int err = 0;
+
+        err = fosa_mutex_lock(&syncobj->mutex);
+        if (err != 0) return err;
+       pthread_cleanup_push(syncobj_cleanup, syncobj);
+
+        while (syncobj->is_work_done == false) {
+                err = fosa_cond_timedwait(&syncobj->cond,
+                                          &syncobj->mutex,
+                                          abstime);
+                if (err != 0) goto locked_error;
+        }
+
+        syncobj->is_work_done = false;
+
+locked_error:;
+       pthread_cleanup_pop(1);
+        return err;
+}
diff --git a/src/forb/src/syncobj.h b/src/forb/src/syncobj.h
new file mode 100644 (file)
index 0000000..6127858
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef SYNC_OBJ_H
+#define SYNC_OBJ_H
+
+//----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politecnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org
+//
+//        The FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+// This file is part of DTM (Distributed Transaction Manager)
+//
+// DTM is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version.  DTM is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with DTM; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including DTM header files in a file,
+// instantiating DTM generics or templates, or linking other files
+// with DTM objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*!
+ * @file syncobj.h
+ *
+ * @brief Synchronization objects
+ *
+ * This module contains the definition of simple synchronization
+ * objects built on top FOSA condition variables.
+ *
+ * @author Michael Gonzalez Harbour <mgh@unican.es>
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ */
+
+#ifndef _SYNC_OBJ_H_
+#define _SYNC_OBJ_H_
+
+#include <fosa_mutexes_and_condvars.h>
+#include <time.h> /* for timespec */
+#include <fosa_opaque_types.h> /* for FOSA_ETIMEDOUT */
+
+/**
+ * Semaphore-like synchronization object build on top of FOSA's
+ * condition variables.
+ */
+typedef struct forb_syncobj {
+        bool is_work_done;
+        fosa_cond_t cond;
+        fosa_mutex_t mutex;
+} forb_syncobj_t;
+
+
+extern int forb_syncobj_init(forb_syncobj_t *syncobj, int ceiling);
+extern int forb_syncobj_destroy(forb_syncobj_t *syncobj);
+extern int forb_syncobj_signal(forb_syncobj_t *syncobj);
+extern int forb_syncobj_wait(forb_syncobj_t *syncobj);
+extern int forb_syncobj_timedwait(forb_syncobj_t *syncobj,
+                                 const struct timespec *abstime);
+#define FORB_ETIMEDOUT FOSA_ETIMEDOUT
+
+#endif // _SYNC_OBJ_H_
+
+
+#endif
diff --git a/src/forb/src/tests/Makefile b/src/forb/src/tests/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/forb/src/tests/Makefile.omk b/src/forb/src/tests/Makefile.omk
new file mode 100644 (file)
index 0000000..a81f884
--- /dev/null
@@ -0,0 +1,46 @@
+SUBDIRS = $(ALL_OMK_SUBDIRS)
+
+test_PROGRAMS += hello_inproc hello_remote test_proto_inet discovery   \
+               syncobj regobjref
+ifeq ($(CONFIG_FORB_PROTO_UNIX),y)
+test_PROGRAMS += test_proto_unix
+endif
+
+wvtest_PROGRAMS += sequence
+sequence_SOURCES = sequence.c
+sequence_CLIENT_IDL = sequence.idl
+sequence_LIBS = wvtest
+
+CFLAGS += -DTEST -DWVTEST_CONFIGURED
+INCLUDES += -I.
+
+lib_LOADLIBES = forb ulut fosa rt
+
+hello_inproc_SOURCES = hello_inproc.c hello_impl.c
+hello_inproc_CLIENT_IDL = hello.idl
+hello_inproc_SERVER_IDL = hello.idl
+
+hello_remote_SOURCES = hello_remote.c hello_impl.c
+hello_remote_CLIENT_IDL = hello.idl
+hello_remote_SERVER_IDL = hello.idl
+
+regobjref_SOURCES = regobjref.c hello_impl.c
+regobjref_CLIENT_IDL = hello.idl
+regobjref_SERVER_IDL = hello.idl
+
+include_GEN_HEADERS = hello.h
+
+# test_PROGRAMS += hello_client
+# hello_client_SOURCES = hello_client.c
+# hello_inproc_CLIENT_IDL = hello.idl
+
+# test_PROGRAMS += hello_server
+# hello_server_SOURCES = hello_server.c
+# hello_inproc_SERVER_IDL = hello.idl
+
+test_proto_unix_SOURCES = test_proto_unix.c
+test_proto_inet_SOURCES = test_proto_inet.c
+
+discovery_SOURCES = discovery.c
+
+syncobj_SOURCES = test_syncobj.c
diff --git a/src/forb/src/tests/discovery.c b/src/forb/src/tests/discovery.c
new file mode 100644 (file)
index 0000000..48b0a08
--- /dev/null
@@ -0,0 +1,118 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   discovery.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 19:05:27 2008
+ * 
+ * @brief  Test for correctness of peer discovery protocol
+ * 
+ * Multiple FORB obejcts are created and it is tested whether every
+ * FORB automatically discovers the other FORBs.
+ */
+
+#include <stdbool.h>
+#include <forb.h>
+#include <forb/object.h>
+#include <forb/forb-internal.h>
+#include <forb/config.h>
+#include <unistd.h>
+#include "../proto.h"
+#include "../discovery.h"
+#include <error.h>
+#include <fosa.h>
+#include <stdio.h>
+
+#define NUM_ORBS 5
+
+#if !CONFIG_FORB_PROTO_UNIX && !CONFIG_FORB_PROTO_INET_DEFAULT
+#error This test should only work if there is some local protocol enabled.
+#endif
+
+int main(int argc, char *argv[])
+{
+       forb_orb orb[NUM_ORBS];
+       int i;
+       bool all_peers_found = true;
+       fosa_abs_time_t timeout;
+
+       for (i=0; i<NUM_ORBS; i++) {
+               orb[i] = forb_init(&argc, &argv, NULL);
+               if (!orb[i]) {
+                       error(1, errno, "Orb no. %d was not created\n", i);
+               }
+       }
+
+       fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &timeout);
+       timeout = fosa_abs_time_incr(timeout,
+                                    fosa_msec_to_rel_time(1000));
+
+       /* Check whether all the peers are found */
+       for (i=0; i<NUM_ORBS && all_peers_found; i++) {
+               int j;
+               forb_peer_t *peer;
+               for (j=0; j<NUM_ORBS && all_peers_found; j++) {
+                       if (i==j) continue;
+                       peer = forb_peer_find_timed(forb_data(orb[i]),
+                                                   &forb_data(orb[j])->server_id,
+                                                   &timeout);
+
+                       all_peers_found &= (peer != NULL);
+                       if (!all_peers_found) {
+                               char id[100];
+                               error(1, 0, "Peer %d (%s) was not discovered on node %d",
+                                     j, forb_uuid_to_string(id,
+                                                            (forb_uuid_t*)&forb_data(orb[i])->server_id.uuid,
+                                                            sizeof(id)),
+                                     i);
+                       }
+               }
+       }
+
+       printf("OK\n");
+       return 0;
+}
diff --git a/src/forb/src/tests/hello.idl b/src/forb/src/tests/hello.idl
new file mode 100644 (file)
index 0000000..6bcb4d6
--- /dev/null
@@ -0,0 +1,12 @@
+/**
+ * @file   hello.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 19:07:24 2008
+ * 
+ * @brief  Definition of hello interface
+ * 
+ * 
+ */
+interface hello {
+       void message(in string msg);
+};
diff --git a/src/forb/src/tests/hello_impl.c b/src/forb/src/tests/hello_impl.c
new file mode 100644 (file)
index 0000000..8f4ffdf
--- /dev/null
@@ -0,0 +1,73 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   hello_impl.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 19:07:44 2008
+ * 
+ * @brief Implementation of hello interfaces shared between multiple
+ * tests.
+ * 
+ * 
+ */
+
+#include <hello.h>
+#include <stdio.h>
+
+static void message(hello _obj, const CORBA_char * msg, CORBA_Environment *ev)
+{
+       printf("Hello object received: %s\n", msg);
+}
+
+static const struct forb_hello_impl impl = {
+       message
+};
+
+forb_object hello_impl_initialize(forb_orb orb)
+{
+       return forb_hello_new(orb, &impl, NULL);
+}
diff --git a/src/forb/src/tests/hello_impl.h b/src/forb/src/tests/hello_impl.h
new file mode 100644 (file)
index 0000000..677ca8b
--- /dev/null
@@ -0,0 +1,64 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   hello_impl.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 19:08:20 2008
+ * 
+ * @brief  Interface to the common hello implementation
+ * 
+ * 
+ */
+
+#ifndef HELLO_IMPL_H
+#define HELLO_IMPL_H
+
+#include <hello.h>
+
+forb_object hello_impl_initialize(forb_orb orb);
+
+#endif
diff --git a/src/forb/src/tests/hello_inproc.c b/src/forb/src/tests/hello_inproc.c
new file mode 100644 (file)
index 0000000..701c908
--- /dev/null
@@ -0,0 +1,83 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   hello_inproc.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 19:08:46 2008
+ * 
+ * @brief  Test of in-process invocation
+ * 
+ * 
+ */
+
+#include <hello.h>
+#include "hello_impl.h"
+#include <forb.h>
+#include <error.h>
+
+int main(int argc, char *argv[])
+{
+       forb_orb orb;
+       hello hobj;
+       struct forb_env env;
+       struct forb_init_attr attr = {
+               .orb_id = "hello_inproc"
+       };
+               
+       orb = forb_init(&argc, &argv, &attr);
+       if (!orb) {
+               error(1, errno, "Cannot initialize FORB");
+       }
+       hobj = hello_impl_initialize(orb);
+
+       hello_message(hobj, "Hello world!", &env);
+       if (forb_exception_occurred(&env)) {
+               error(1, 0, "FORB exception %d", env.major);
+       }
+               
+       return 0;       
+}
diff --git a/src/forb/src/tests/hello_remote.c b/src/forb/src/tests/hello_remote.c
new file mode 100644 (file)
index 0000000..aa6f726
--- /dev/null
@@ -0,0 +1,142 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   hello_remote.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Thu Sep 25 16:05:27 2008
+ * 
+ * @brief  Test of remote invocation.
+ *
+ * In this test, two FORBs are created, one for running the server of
+ * hello interface and the second for running the client code. Since
+ * the client and server are registered in different FORBs, remote
+ * communication is used even if the two FORBs share the same
+ * memory. This way we can easily test remote communication without
+ * writing separate applications for client and server.
+ */
+
+#include <hello.h>
+#include "hello_impl.h"
+#include <forb.h>
+#include <error.h>
+#include <fosa.h>
+#include <forb/executor.h>
+
+int argc_g;
+char **argv_g;
+
+void *server_thread(void *arg)
+{
+       hello hobj = arg;
+
+       forb_execute_object(hobj);
+       return NULL;
+}
+
+char *start_server()
+{
+       forb_orb orb;
+       hello hobj;
+
+       fosa_thread_id_t tid;
+       struct forb_init_attr attr = {
+               .orb_id = "hello_remote_server"
+       };
+               
+       orb = forb_init(&argc_g, &argv_g, &attr);
+       if (!orb) {
+               error(1, errno, "Cannot initialize FORB for server");
+       }
+       hobj = hello_impl_initialize(orb);
+       fosa_thread_create(&tid, NULL, server_thread, hobj);
+
+       return forb_object_to_string(hobj);
+}
+
+
+
+void client(void *arg)
+{
+       forb_orb orb;
+       hello hobj;
+       struct forb_env env;
+       char *objref = arg;
+       struct forb_init_attr attr = {
+               .orb_id = "hello_remote_client"
+       };
+               
+       orb = forb_init(&argc_g, &argv_g, &attr);
+       if (!orb) {
+               error(1, errno, "Cannot initialize FORB for server");
+       }
+
+       hobj = forb_string_to_object(orb, objref);
+       if (!hobj) {
+               error(1, 0, "Cannot create object reference from the string (%s)\n", objref);
+       }
+
+       hello_message(hobj, "Hello world!", &env);
+       if (forb_exception_occurred(&env)) {
+               error(1, 0, "FORB exception %d", env.major);
+       }
+
+}
+
+int main(int argc, char *argv[])
+{
+
+       char *objref_str;
+       
+       argc_g = argc;
+       argv_g = argv;
+
+       objref_str = start_server();
+
+       client(objref_str);
+               
+       return 0;       
+}
diff --git a/src/forb/src/tests/object_to_string/Makefile b/src/forb/src/tests/object_to_string/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/forb/src/tests/object_to_string/Makefile.omk b/src/forb/src/tests/object_to_string/Makefile.omk
new file mode 100644 (file)
index 0000000..f8ca37d
--- /dev/null
@@ -0,0 +1,8 @@
+test_PROGRAMS = obj2str
+obj2str_SOURCES = obj2str.c
+obj2str_SERVER_IDL = interface.idl
+
+CFLAGS += -I.
+
+
+lib_LOADLIBES = forb ulut fosa rt
diff --git a/src/forb/src/tests/object_to_string/interface.idl b/src/forb/src/tests/object_to_string/interface.idl
new file mode 100644 (file)
index 0000000..6661304
--- /dev/null
@@ -0,0 +1,3 @@
+interface i {
+       void method();
+};
diff --git a/src/forb/src/tests/object_to_string/obj2str.c b/src/forb/src/tests/object_to_string/obj2str.c
new file mode 100644 (file)
index 0000000..8fe6545
--- /dev/null
@@ -0,0 +1,103 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   obj2str.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 19:10:23 2008
+ * 
+ * @brief  Test for forb_object_to_string() and forb_string_to_object()
+ * 
+ * 
+ */
+
+#include <forb.h>
+#include <stdio.h>
+#include "interface.h"
+#include <error.h>
+#include <string.h>
+
+struct forb_i_impl i_impl =  { NULL };
+
+int main(int argc, char *argv[])
+{
+       forb_object orb, obj, obj2;
+       char *str, *str2;
+       struct forb_init_attr attr = {
+               .orb_id = "obj2str"
+       };
+               
+       orb = forb_init(&argc, &argv, &attr);
+
+       obj = forb_i_new(orb, &i_impl, NULL);
+       if (!obj) {
+               error(1, errno, "Object was not created");
+       }
+
+       str = forb_object_to_string(obj);
+       if (str) {
+               printf("Object reference1: %s\n", str);
+       } else {
+               return 1;
+       }
+
+       obj2 = forb_string_to_object(orb, str);
+
+       str2 = forb_object_to_string(obj2);
+       if (str) {
+               printf("Object reference2: %s\n", str2);
+       } else {
+               return 1;
+       }
+
+       if (strcmp(str, str2) != 0) 
+               error(1, 0, "Object references should be the same");
+       
+       forb_free(str);
+       forb_free(str2);
+
+       return 0;
+}
diff --git a/src/forb/src/tests/objref/Makefile b/src/forb/src/tests/objref/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/forb/src/tests/objref/Makefile.omk b/src/forb/src/tests/objref/Makefile.omk
new file mode 100644 (file)
index 0000000..a4e580e
--- /dev/null
@@ -0,0 +1,9 @@
+test_PROGRAMS = objref
+
+lib_LOADLIBES = forb ulut fosa rt
+
+objref_SOURCES = objref.c
+objref_CLIENT_IDL = objref.idl
+objref_SERVER_IDL = objref.idl
+
+INCLUDES += -I$(USER_OBJS_DIR)
diff --git a/src/forb/src/tests/objref/objref.c b/src/forb/src/tests/objref/objref.c
new file mode 100644 (file)
index 0000000..f16058a
--- /dev/null
@@ -0,0 +1,172 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   objref.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Thu Oct  2 15:32:17 2008
+ * 
+ * @brief  Test for passing object references as method parameters
+ *
+ * In this test a client calls server's method call_me_back(), which
+ * takes a client object reference as parameter. The server then
+ * invokes the callback() method on the received object reference.
+ * 
+ */
+
+#include <forb.h>
+#include <error.h>
+#include <fosa.h>
+#include <forb/executor.h>
+#include "objref.h"
+#include <stdio.h>
+#include <stdbool.h>
+
+int argc_g;
+char **argv_g;
+
+static void call_me_back(server _obj, const client obj, CORBA_Environment *ev)
+{
+       CORBA_Environment env;
+       printf("Server called\n");
+       client_callback(obj, &env);
+}
+
+static const struct forb_server_impl server_impl = {
+       .call_me_back = call_me_back
+};
+
+
+void *server_thread(void *arg)
+{
+       server s = arg;
+       forb_execute_object(s);
+       return NULL;
+}
+
+char *start_server()
+{
+       forb_orb orb;
+       server s;
+       fosa_thread_id_t tid;
+       struct forb_init_attr attr = {
+               .orb_id = "objref_server"
+       };
+               
+       orb = forb_init(&argc_g, &argv_g, &attr);
+       s = forb_server_new(orb, &server_impl, NULL);
+       fosa_thread_create(&tid, NULL, server_thread, s);
+
+       return forb_object_to_string(s);
+}
+
+unsigned callback_called = 0;
+
+static void callback(client _obj, CORBA_Environment *ev)
+{
+       callback_called++;
+       printf("Client callback called %d times\n", callback_called);
+}
+
+static const struct forb_client_impl client_impl = {
+       .callback = callback
+};
+
+void *client_thread(void *arg)
+{
+       client c = arg;
+       forb_execute_object(c);
+       return NULL;
+}
+
+
+void start_client(void *arg)
+{
+       char *objref = arg;
+       forb_orb orb;
+       server serv;
+       client me;
+       struct forb_env env;
+       fosa_thread_id_t tid;
+       struct forb_init_attr attr = {
+               .orb_id = "objref_client"
+       };
+               
+       orb = forb_init(&argc_g, &argv_g, &attr);
+
+       me = forb_client_new(orb, &client_impl, NULL);
+       fosa_thread_create(&tid, NULL, client_thread, me);
+
+       serv = forb_string_to_object(orb, objref);
+       if (!serv) {
+               error(1, 0, "Cannot create object reference from the string (%s)\n", objref);
+       }
+
+       server_call_me_back(serv, me, &env);
+       if (forb_exception_occurred(&env)) {
+               error(1, 0, "FORB exception %d", env.major);
+       }
+
+       forb_object_release(me);
+}
+
+int main(int argc, char *argv[])
+{
+
+       char *objref_str;
+
+       argc_g = argc;
+       argv_g = argv;
+       
+       objref_str = start_server();
+
+       start_client(objref_str);
+
+       if (callback_called == 0) {
+               error(1, 0, "Callback was not called");
+       }
+       return 0;       
+}
diff --git a/src/forb/src/tests/objref/objref.idl b/src/forb/src/tests/objref/objref.idl
new file mode 100644 (file)
index 0000000..24d6e66
--- /dev/null
@@ -0,0 +1,7 @@
+interface client {
+       void callback();
+};
+
+interface server {
+       void call_me_back(in client obj);
+};
diff --git a/src/forb/src/tests/regobjref.c b/src/forb/src/tests/regobjref.c
new file mode 100644 (file)
index 0000000..814d1ae
--- /dev/null
@@ -0,0 +1,135 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   regobjref.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sat Oct 11 21:12:09 2008
+ * 
+ * @brief  Test for forb_register_reference() and forb_resolve_reference()
+ *
+ * This test is the same as hello_remote.c. The only difference is
+ * that in hello_remote.c, the object reference of the server is
+ * passed as a string to the client, whereas here we use
+ * forb_register_reference()/forb_resolve_reference() for this.
+ */
+
+
+#include <hello.h>
+#include "hello_impl.h"
+#include <forb.h>
+#include <error.h>
+#include <fosa.h>
+#include <forb/executor.h>
+
+int argc_g;
+char **argv_g;
+
+void *server_thread(void *arg)
+{
+       hello hobj = arg;
+
+       forb_execute_object(hobj);
+       return NULL;
+}
+
+void start_server()
+{
+       forb_orb orb;
+       hello hobj;
+       int ret;
+
+       fosa_thread_id_t tid;
+       struct forb_init_attr attr = {
+               .orb_id = "hello_remote_server"
+       };
+
+       orb = forb_init(&argc_g, &argv_g, &attr);
+       hobj = hello_impl_initialize(orb);
+       fosa_thread_create(&tid, NULL, server_thread, hobj);
+
+       ret = forb_register_reference(hobj, "hello");
+       if (ret != 0) {
+               error(1, errno, "Cannot register reference to hello");
+       }
+}
+
+
+
+void client(void)
+{
+       forb_orb orb;
+       hello hobj;
+       struct forb_env env;
+       struct forb_init_attr attr = {
+               .orb_id = "hello_remote_client"
+       };
+               
+       orb = forb_init(&argc_g, &argv_g, &attr);
+
+       hobj = forb_resolve_reference(orb, "hello");
+       if (!hobj) {
+               error(1, errno, "Cannot resolve reference to hello server)");
+       }
+
+       hello_message(hobj, "Hello world!", &env);
+       if (forb_exception_occurred(&env)) {
+               error(1, 0, "FORB exception %d", env.major);
+       }
+}
+
+int main(int argc, char *argv[])
+{
+
+       argc_g = argc;
+       argv_g = argv;
+
+       start_server();
+
+       client();
+               
+       return 0;       
+}
diff --git a/src/forb/src/tests/sequence.c b/src/forb/src/tests/sequence.c
new file mode 100644 (file)
index 0000000..92c5448
--- /dev/null
@@ -0,0 +1,60 @@
+#include <forb.h>
+#include <wvtest.h>
+#include "sequence.h"
+
+int destructor_called;
+int sum_of_destructed;
+
+void destructor(int *elem)
+{
+       destructor_called++;
+       sum_of_destructed += *elem;
+}
+
+WVTEST_MAIN("sequence manipulation")
+{
+       CORBA_sequence_long *s;
+       int i, *e, foreach_retuned_sum = 0;
+       forb_sequence_alloc(s, 10);
+       WVPASS(s);
+       WVPASS(forb_sequence_allocated(s) == 10);
+       bool initialized_to_zero = true;
+       for (i=0; i<10; i++)
+               initialized_to_zero &= forb_sequence_elem(s, i) == 0;
+       WVPASS(initialized_to_zero);
+       WVPASS(forb_sequence_elem(s, 9) = 1);
+       WVPASS(forb_sequence_ensure_allocated(s, 1000) != NULL);
+       WVPASS(forb_sequence_allocated(s) == 1000);
+       WVPASS(forb_sequence_elem(s, 9) == 1);
+       WVPASS(forb_sequence_elem(s, 999) = 1);
+       CORBA_sequence_set_release(s, 1);
+       WVPASS(forb_sequence_length(s) == 0);
+       forb_sequence_free(s, destructor);
+       WVPASS(destructor_called == 0);
+
+       forb_sequence_alloc(s, 10);
+       WVPASS(s);
+       for (i=0; i<10; i++)
+               forb_sequence_elem(s, i) = i;
+       forb_sequence_length(s) = 10;
+       WVPASS(forb_sequence_length(s) == 10);
+       forb_sequence_free(s, destructor);
+       WVPASS(destructor_called == 0);
+
+       forb_sequence_alloc(s, 10);
+       WVPASS(s);
+       CORBA_sequence_set_release(s, 1);
+       for (i=0; i<10; i++)
+               forb_sequence_elem(s, i) = i;
+       forb_sequence_length(s) = 10;
+       WVPASS(forb_sequence_length(s) == 10);
+
+       forb_sequence_foreach(s, e) {
+               foreach_retuned_sum += *e;
+       }
+       WVPASS(foreach_retuned_sum == 45);
+       
+       forb_sequence_free(s, destructor);
+       WVPASS(destructor_called == 10);
+       WVPASS(sum_of_destructed == 45);
+}
diff --git a/src/forb/src/tests/sequence.idl b/src/forb/src/tests/sequence.idl
new file mode 100644 (file)
index 0000000..8ab9d63
--- /dev/null
@@ -0,0 +1,12 @@
+interface MyIface {
+       void MyOp();
+};
+
+struct SeqStruct {
+       sequence<long,10> MyLongs;
+       sequence<octet> MyOctets;
+//     sequence<MyIface> Interfaces; FIXME: This is bugy: sequence-common.c:124: undefined reference to `CORBA_sequence_Object_deserialize
+       sequence<sequence<short> > SeqSeq;
+};
+
+typedef sequence<string> MyStrings;
diff --git a/src/forb/src/tests/test_proto_inet.c b/src/forb/src/tests/test_proto_inet.c
new file mode 100644 (file)
index 0000000..25e8348
--- /dev/null
@@ -0,0 +1,147 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   test_proto_inet.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Thu Aug 28 15:20:37 2008
+ * 
+ * @brief Unit test for INET socket based FORB transport protocol
+ */
+
+#include <error.h>
+#include "../proto_inet.c"
+
+const char *msg = "Hello world!";
+const char *msg2 = "Blablabla!";
+#define NUM_PORTS 10
+
+char *timeout_msg = "timeout\n";
+
+void timeout(int signal)
+{
+       error(1, 0, timeout_msg);
+}
+
+int main()
+{
+       int len;
+       struct inet_addr addr[NUM_PORTS];
+       forb_port_t port[NUM_PORTS];
+       int i, ret;
+
+       signal(SIGALRM, timeout);
+
+       memset(port, 0, sizeof(port));
+
+       for (i=0; i<NUM_PORTS; i++) {
+               addr[i].addr.s_addr = htonl(0x7f000001+i);
+               if (forb_inet_port_init(&port[i].desc, addr[i].addr, 0) != 0)
+                       error(1, errno, "forb_inet_port_init(%d)", i);
+       }
+
+
+       /* Send from zeroth node to all others (starting from 1) */
+       for (i=1; i<NUM_PORTS; i++) {
+               forb_peer_t *peer;
+               char buf[100];
+               char tmsg[100];
+
+               peer = forb_peer_new();
+               peer->addr = port[i].desc.addr;
+               peer->port = &port[0];
+               
+               len = strlen(msg)+1;
+               ret = inet_send(peer, msg, len);
+
+               peer->addr = NULL;
+               forb_peer_put(peer);
+               if (ret != len)
+                       error(1, errno, "send(to %d) = %d", i, ret);
+
+               sprintf(tmsg, "Timeout when sending from 0 to %d\n", i);
+               timeout_msg = tmsg;
+               alarm(1);       /* timeout 1s */
+               ret = inet_recv(&port[i], buf, sizeof(buf));
+               alarm(0);
+               if (ret != len)
+                       error(1, errno, "recv(port[%d]) = %d", i, ret);
+
+               if (strcmp(msg, buf) != 0)
+                       error(1, errno, "port %d: received wrong data", i);
+
+       }
+
+       len = strlen(msg2)+1;
+       ret = inet_broadcast(&port[0], msg2, len);
+       if (ret != len) 
+               error(1, errno, "broadcast(port[0]) = %d should be %d", ret, len);
+       
+       for (i=0; i<NUM_PORTS; i++) {
+               char buf[100];
+               char tmsg[100];
+
+               sprintf(tmsg, "Timeout when receiving broadcast for port %d\n", i);
+               timeout_msg = tmsg;
+               alarm(1);
+               ret = inet_recv(&port[i], buf, sizeof(buf));
+               alarm(0);
+               if (ret != len) 
+                       error(1, errno, "broadcast recv(port[%d]) = %d should be %d (errno=%d)", i, ret, len, errno);
+               //printf("broadcast received: %s\n", buf);
+
+               if (strcmp(msg2, buf) != 0)
+                       error(1, errno, "port %d: broadcast received wrong data", i);
+
+       }
+
+       for (i=0; i<NUM_PORTS; i++) {
+               inet_port_destroy(&port[i]);
+       }
+
+       printf("OK\n");
+       return 0;
+}
diff --git a/src/forb/src/tests/test_proto_unix.c b/src/forb/src/tests/test_proto_unix.c
new file mode 100644 (file)
index 0000000..b920b19
--- /dev/null
@@ -0,0 +1,141 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   test_proto_unix.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Thu Aug 28 15:20:37 2008
+ * 
+ * @brief Unit test for UNIX socket based FORB transport protocol
+ */
+
+#include <error.h>
+#include "../proto_unix.c"
+
+const char *msg = "Hello world!";
+const char *msg2 = "Blablabla!";
+#define NUM_PORTS 10
+
+char *timeout_msg = "timeout\n";
+
+void timeout(int signal)
+{
+       error(1, 0, timeout_msg);
+}
+
+int main()
+{
+       int len;
+       forb_server_id server[NUM_PORTS];
+       forb_port_t port[NUM_PORTS];
+       int i, ret;
+
+       signal(SIGALRM, timeout);
+
+       for (i=0; i<NUM_PORTS; i++) {
+               forb_server_id_init(&server[i]);
+               if (forb_unix_port_init(&port[i].desc, &server[i]) != 0)
+                       error(1, errno, "forb_unix_port_init(%d)", i);
+       }
+
+
+       /* Send from zeroth node to all others (starting from 1) */
+       for (i=1; i<NUM_PORTS; i++) {
+               forb_peer_t peer;
+               char buf[100];
+               char tmsg[100];
+
+               peer.server_id = server[i];
+               peer.port = &port[0];
+               
+               len = strlen(msg)+1;
+               ret = unix_send(&peer, msg, len);
+               if (ret != len) 
+                       error(1, errno, "send(to %d) = %d", i, ret);
+
+               sprintf(tmsg, "Timeout when sending from 0 to %d\n", i);
+               timeout_msg = tmsg;
+               alarm(1);       /* timeout 1s */
+               ret = unix_recv(&port[i], buf, sizeof(buf));
+               alarm(0);
+               if (ret != len) 
+                       error(1, errno, "recv(port[%d]) = %d", i, ret);
+
+               if (strcmp(msg, buf) != 0)
+                       error(1, errno, "port %d: received wrong data", i);
+
+       }
+
+
+       len = strlen(msg2)+1;
+       ret = unix_broadcast(&port[0], msg2, len);
+       if (ret != len) 
+               error(1, errno, "broadcast(port[0]) = %d should be %d", ret, len);
+       
+       for (i=0; i<NUM_PORTS; i++) {
+               char buf[100];
+               char tmsg[100];
+
+               sprintf(tmsg, "Timeout when receiving broadcast for port %d\n", i);
+               timeout_msg = tmsg;
+               alarm(1);
+               ret = unix_recv(&port[i], buf, sizeof(buf));
+               alarm(0);
+               if (ret != len) 
+                       error(1, errno, "broadcast recv(port[%d]) = %d should be %d", i, ret, len);
+               //printf("broadcast received: %s\n", buf);
+
+               if (strcmp(msg2, buf) != 0)
+                       error(1, errno, "port %d: broadcast received wrong data", i);
+
+       }
+
+       for (i=0; i<NUM_PORTS; i++) {
+               unix_port_destroy(&port[i]);
+       }
+
+       return 0;
+}
diff --git a/src/forb/src/tests/test_syncobj.c b/src/forb/src/tests/test_syncobj.c
new file mode 100644 (file)
index 0000000..7e75a3c
--- /dev/null
@@ -0,0 +1,108 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   test_syncobj.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 19:09:45 2008
+ * 
+ * @brief  Test of synchronization obects
+ * 
+ * 
+ */
+
+#include <stdio.h>
+#include <forb/syncobj.h>
+#include <fosa.h>
+#include <error.h>
+
+forb_syncobj_t syncobj;
+
+void *thread(void *arg)
+{
+       fosa_abs_time_t now, hello_time;
+       fosa_rel_time_t hello_interval = fosa_msec_to_rel_time(2000);
+       int ret;
+
+       fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &hello_time);
+       hello_time = fosa_abs_time_incr(hello_time, hello_interval);
+       ret = forb_syncobj_timedwait(&syncobj, &hello_time);
+       if (ret != 0) {
+               error(1, errno, "forb_syncobj_timedwait() error %d\n", ret);
+       }
+
+       fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &now);
+       if (fosa_abs_time_smaller_or_equal(hello_time, now)) {
+               error(1, 0, "Should not wait longet than timeout\n");
+       }
+       return NULL;
+}
+
+int main()
+{
+       fosa_abs_time_t now, hello_time;
+       fosa_rel_time_t hello_interval = fosa_msec_to_rel_time(1000);
+       int ret;
+       fosa_thread_id_t tid;
+
+       forb_syncobj_init(&syncobj, 0);
+
+       fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &hello_time);
+       hello_time = fosa_abs_time_incr(hello_time, hello_interval);
+
+       ret = forb_syncobj_timedwait(&syncobj, &hello_time);
+       if (ret != 0 && ret != FOSA_ETIMEDOUT) {
+               error(1, errno, "forb_syncobj_timedwait() error %d\n", ret);
+       }
+       fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &now);
+       if (fosa_abs_time_smaller_or_equal(now, hello_time)) {
+               error(1, 0, "Wait less then timeout\n");
+       }
+
+       fosa_thread_create(&tid, NULL, thread, NULL);
+       forb_syncobj_signal(&syncobj);
+       return 0;
+}
diff --git a/src/forb/src/types.idl b/src/forb/src/types.idl
new file mode 100644 (file)
index 0000000..b4b4ea3
--- /dev/null
@@ -0,0 +1,28 @@
+/**
+ * @file   types.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 17:12:30 2008
+ * 
+ * @brief  Types used internally by FORB.
+ * 
+ * 
+ */
+
+module forb {
+       /**
+        * Object key for distinguishing different objects in a FORB.
+        */
+       typedef long long object_key;
+
+       typedef char uuid[8];
+
+       /**
+        * Server ID for identifying different FORBs.
+        *
+        * The ID is based on universal unique identifiers (UUID).
+        */
+
+       struct server_id {
+               uuid uuid;
+       };
+};
diff --git a/src/forb/src/ul_log_domains b/src/forb/src/ul_log_domains
new file mode 100755 (executable)
index 0000000..3723907
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+ARRAY_NAME=ul_log_domains_array
+
+DIRS=""
+
+while [ $# -gt 0 ] ; do
+  case "x${1}x" in
+    "x--helpx" | "x-hx" )
+      echo -e Usage: `basename ${0}`" [options] <srcdir> .."
+      echo -e "      -h --help       help"
+      echo -e "      -a --array      identifier of log domain array variable"
+      exit 0
+      ;;
+    "x--arrayx" | "x-ax" )
+      shift 1
+      ARRAY_NAME="${1}"
+      ;;
+    "x--"* )
+      echo "Unknown option"
+      exit 2
+      ;;
+    * )
+      DIRS="$DIRS ${1}"
+      ;;
+  esac
+  shift 1
+done
+
+DOMAINS=$( for d in $DIRS ; do find -L $d '(' -name '*.c' -o -name '*.cc' ')' -exec grep UL_LOG_CUST '{}' ';' | \
+  sed -n -e 's/^.*UL_LOG_CUST(\([^)]*\)).*$/\1/p' ; done | sort -u )
+
+#echo $DOMAINS
+
+#echo -e "#define UL_LOGL_DEF UL_LOGL_DEB\n"
+
+echo "/*"
+echo " * This is generated file, do not edit it directly."
+echo " * Take it from standard output of \"ul_log_domains\""
+echo " * script called in the top level project directory"
+echo " */"
+
+for i in $DOMAINS ; do
+  echo "ul_log_domain_t $i     = {UL_LOGL_DEF, \"$(echo -n $i | sed -n -e 's/ulogd_\(.*\)/\1/pg' )\"};"
+done
+
+echo
+echo "ul_log_domain_t *$ARRAY_NAME[] = {"
+
+for i in $DOMAINS ; do
+  echo "  &$i,"
+done
+
+echo "};"
diff --git a/src/forb/src/uuid.c b/src/forb/src/uuid.c
new file mode 100644 (file)
index 0000000..c601432
--- /dev/null
@@ -0,0 +1,155 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+ * @file   uuid.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Tue Aug 26 09:17:31 2008
+ * 
+ * @brief  Unix version of UUID generator
+ * 
+ */
+#include <forb/uuid.h>
+#include <sys/time.h>
+#include <time.h>
+#include "sha1.h"
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/** 
+ * Generates universally unique ID.
+ * 
+ * @param dest Where to store the newly generated UUID.
+ * 
+ * @return Same as @a dest.
+ */
+forb_uuid_t *forb_uuid_generate(forb_uuid_t *dest)
+{
+       SHA1_CTX ctx;
+       struct timeval  tv;
+       pid_t pid = getpid();
+       unsigned char digest[20];
+       int i, r;
+       
+       gettimeofday(&tv, 0);
+
+       SHA1Init(&ctx);
+       SHA1Update(&ctx, (unsigned char*)&tv, sizeof(tv));
+       SHA1Update(&ctx, (unsigned char*)&pid, sizeof(pid));
+
+       /* Crank the random number generator a few times */
+       gettimeofday(&tv, 0);
+       for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) {
+               r = rand();
+               SHA1Update(&ctx, (unsigned char*)&r, sizeof(r));
+       }
+
+       /* Also try to use /dev/urnadom to get some randomnes */
+       
+       /* This should be enough for localhost process.
+        * TODO: Add network addresses for distributed operation! */
+       SHA1Final(digest, &ctx);
+       memcpy(dest, digest, sizeof(forb_uuid_t));
+       return dest;
+}
+
+/** 
+ * Converts UUID to string.
+ * 
+ * @param dest Where to store the result.
+ * @param uuid The UUID to convert.
+ * @param n Size of @a dest buffer.
+ * 
+ * @return The same value as @a dest.
+ */
+char *forb_uuid_to_string(char *dest, const forb_uuid_t *uuid, size_t n)
+{
+       int i;
+       for (i = 0; i<sizeof(uuid->byte) && 2*(i+1) < n; i++)
+               sprintf(dest + 2*i, "%02hhx", uuid->byte[i]);
+       dest[2*i] = '\0';
+       return dest;
+}
+
+static inline int hexval(char c)
+{
+       if (c >= '0' && c <= '9')
+               return c-'0';
+       if (c >= 'a' && c <= 'f')
+               return 10+c-'a';
+       if (c >= 'A' && c <= 'F')
+               return 10+c-'A';
+       return -1;
+}
+
+/** 
+ * Creates UUID from string form.
+ * 
+ * @param dest Where to store the UUID.
+ * @param string UUID in the string form.
+ * 
+ * @return @a dest in case of success, NULL in case of error.
+ */
+forb_uuid_t *forb_uuid_from_string(forb_uuid_t *dest, const char *string)
+{
+       int i;
+       
+       for (i = 0; i<sizeof(dest->byte); i++) {
+               int a, b;
+               a = hexval(string[2*i]);
+               if (a < 0)
+                       return NULL;
+               b = hexval(string[2*i+1]);
+               if (b < 0)
+                       return NULL;
+
+               dest->byte[i] = (a << 4) + b;
+       }
+       return dest;
+}
+
diff --git a/src/forb/src/uuid.h b/src/forb/src/uuid.h
new file mode 100644 (file)
index 0000000..7279ed8
--- /dev/null
@@ -0,0 +1,76 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FORB (Frescor Object Request Broker)            */
+/*                                                                       */
+/* FORB is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FORB is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FORB; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FORB header files in a file,        */
+/* instantiating FORB generics or templates, or linking other files      */
+/* with FORB objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+#ifndef FORB_UUID_H
+#define FORB_UUID_H
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Universally unique ID type.
+ */
+typedef struct {
+       char byte[8];
+} forb_uuid_t;
+
+static inline int forb_uuid_cmp(forb_uuid_t u1, forb_uuid_t u2)
+{
+       return memcmp(&u1, &u2, sizeof(forb_uuid_t));
+}
+
+forb_uuid_t *forb_uuid_generate(forb_uuid_t *dest);
+char *forb_uuid_to_string(char *dest, const forb_uuid_t *uuid, size_t n);
+forb_uuid_t *forb_uuid_from_string(forb_uuid_t *dest, const char *string);
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif
diff --git a/src/forb/tests-idl/Makefile b/src/forb/tests-idl/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/forb/tests-idl/Makefile.omk b/src/forb/tests-idl/Makefile.omk
new file mode 100644 (file)
index 0000000..0990c42
--- /dev/null
@@ -0,0 +1,23 @@
+#SUBDIRS = $(ALL_OMK_SUBDIRS)
+
+USER_IDLS += $(notdir $(wildcard $(SOURCES_DIR)/*.idl))
+
+library-pass_HOOKS = $(foreach idl,$(USER_IDLS),$(idl:%.idl=%.h))
+
+lib_LIBRARIES = forb-idl-tests
+# Test whether are the generated files compilable
+forb-idl-tests_GEN_SOURCES = $(addsuffix -skels.c,$(basename $(USER_IDLS))) \
+                            $(addsuffix -stubs.c,$(basename $(USER_IDLS))) \
+                            $(addsuffix -common.c,$(basename $(USER_IDLS)))
+
+test_PROGRAMS += example_server
+INCLUDES += -I$(USER_OBJS_DIR)
+example_server_SOURCES = example_server.c
+example_server_LIBS = fosa pthread rt forb ulut
+example_server_SERVER_IDL = myinterface.idl
+
+test_PROGRAMS += example_client
+INCLUDES += -I$(USER_OBJS_DIR)
+example_client_SOURCES = example_client.c
+example_client_LIBS = fosa pthread rt forb ulut
+example_client_CLIENT_IDL = myinterface.idl
diff --git a/src/forb/tests-idl/enum.idl b/src/forb/tests-idl/enum.idl
new file mode 100644 (file)
index 0000000..7151efa
--- /dev/null
@@ -0,0 +1,6 @@
+enum MyEnum {
+       ONE_VALUE,
+       SECOND_VALUE
+};
+
+typedef MyEnum TypedeffedEnum;
diff --git a/src/forb/tests-idl/example_client.c b/src/forb/tests-idl/example_client.c
new file mode 100644 (file)
index 0000000..f06931b
--- /dev/null
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <forb.h>
+#include "myinterface.h"  /* IDL compiler generated prototypes etc. */
+
+int main(int argc, char *argv[])
+{
+       forb_orb orb;
+       myinterface example;
+       CORBA_Environment env;
+       CORBA_long sum, a, b;
+
+       orb = forb_init(&argc, &argv, NULL); /* FORB initialization */
+
+       /* Find our implementation */
+       example = forb_resolve_reference(orb, "example");
+
+       /* Call our implementation */
+       sum = myinterface_add(example, 2, 3, &env);
+       printf("2+3=%d\n", sum);
+
+       /* Call our implementation again */
+       myinterface_get_last(example, &a, &b, &env);
+       printf("last used values: %d and %d\n", a, b);
+
+       return 0;
+}
diff --git a/src/forb/tests-idl/example_server.c b/src/forb/tests-idl/example_server.c
new file mode 100644 (file)
index 0000000..15c0b04
--- /dev/null
@@ -0,0 +1,52 @@
+#include <forb.h>
+#include "myinterface.h"  /* IDL compiler generated prototypes etc. */
+
+/* Internal data of our object implementing myinterface */
+struct example_data {
+       int last_a, last_b;
+};
+
+/* Implementation of add method */
+CORBA_long example_add(myinterface obj, const CORBA_long a,
+                      const CORBA_long b, CORBA_Environment *ev)
+{
+       struct example_data *ed = forb_instance_data(obj);
+       ed->last_a = a;
+       ed->last_b = b;
+       return a + b;
+}
+
+/* Implementation of get_last method */
+void example_get_last(myinterface obj, CORBA_long* a,
+                     CORBA_long* b, CORBA_Environment *ev)
+{
+       struct example_data *ed = forb_instance_data(obj);
+       *a = ed->last_a;
+       *b = ed->last_b;
+}
+
+/* Table of implemented methods */
+struct forb_myinterface_impl example_implementation = {
+       .add = example_add,
+       .get_last = example_get_last,
+};
+
+int main(int argc, char *argv[])
+{
+       forb_orb orb;
+       myinterface example;
+       struct example_data example_data;
+       
+       orb = forb_init(&argc, &argv, NULL); /* FORB initialization */
+       /* Cration of an object implementing myinterface */
+       example = forb_myinterface_new(orb, &example_implementation,
+                                      &example_data);
+       /* We can register our object under a name, so that other
+        * processes can use it. */
+       forb_register_reference(example, "example");
+
+       /* Process incomming requests to this object */
+       forb_execute_object(example);
+       
+       return 0;               /* Never returns */
+}
diff --git a/src/forb/tests-idl/myinterface.idl b/src/forb/tests-idl/myinterface.idl
new file mode 100644 (file)
index 0000000..f2a674a
--- /dev/null
@@ -0,0 +1,16 @@
+struct struct_t {
+       long a, b;
+};
+
+typedef long mytype;
+
+interface myinterface {
+       long add(in long a, in long b);
+       void get_last(out long a, out long b);
+       void square(inout long r);
+       void message(in string msg);
+       void last_message(out string msg);
+       void struct_method(in struct_t s, out struct_t ss);
+       void obj_method(in myinterface mi, out myinterface mo);
+       void mytype_method(in mytype mt, out mytype mtt);
+};
diff --git a/src/forb/tests-idl/sequence.idl b/src/forb/tests-idl/sequence.idl
new file mode 100644 (file)
index 0000000..1a71a48
--- /dev/null
@@ -0,0 +1,12 @@
+interface MyIface {
+       void MyOp();
+};
+
+struct SeqStruct {
+       sequence<long,10> MyLongs;
+       sequence<octet> MyOctets;
+       sequence<MyIface> Interfaces;
+       sequence<sequence<short> > SeqSeq;
+};
+
+typedef sequence<string> MyStrings;
diff --git a/src/forb/tests-idl/string_test.idl b/src/forb/tests-idl/string_test.idl
new file mode 100644 (file)
index 0000000..899010a
--- /dev/null
@@ -0,0 +1,7 @@
+struct StringStruct {
+       string x;
+};
+
+interface StringIntf {
+       void method(in string s1, out string s2);
+};
diff --git a/src/forb/tests-idl/struct.idl b/src/forb/tests-idl/struct.idl
new file mode 100644 (file)
index 0000000..66cfe68
--- /dev/null
@@ -0,0 +1,7 @@
+struct MyStruct {
+       short d1, d2;
+       long d3[3][6];
+       struct InnerStruct {
+               long data;
+       } d4;
+};
diff --git a/src/forb/tests-idl/typedef.idl b/src/forb/tests-idl/typedef.idl
new file mode 100644 (file)
index 0000000..4319cec
--- /dev/null
@@ -0,0 +1,4 @@
+#include "struct.idl"
+
+typedef MyStruct TypedefedStruct;
+typedef long MyLong, MyLongArray[20];
diff --git a/src/frsh-forb.el b/src/frsh-forb.el
new file mode 100644 (file)
index 0000000..12bf5ed
--- /dev/null
@@ -0,0 +1,65 @@
+;;; frsh-forb.el --- Helper functions for editing FRSH/FORB sources
+
+;; Copyright (C) 2010  Michal Sojka
+
+;; Author: Michal Sojka <sojkam1@fel.cvut.cz>
+;; Keywords: c, files, convenience
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; 
+
+;;; Code:
+
+(defun update-fres-error-c ()
+  "When called from fres_error.h it updates fres_error.c to match
+the list if defined errors"
+  (save-excursion
+    (beginning-of-buffer)
+    (let* ((beg (progn
+                 (re-search-forward "^enum fres_error \{")
+                 (beginning-of-line 2)
+                 (point)))
+          (end (progn
+                 (search-forward "}")
+                 (beginning-of-line)
+                 (point))))
+      (let ((errors))
+       (save-restriction
+         (narrow-to-region beg end)
+         (goto-char (point-min))
+         (while (re-search-forward "^[[:space:]]*FRES_ERR_" nil t)
+           (push (current-word) errors)))
+       (save-current-buffer
+         (set-buffer (find-file-noselect "fres_error.c"))
+         (beginning-of-buffer)
+         (search-forward "switch (e) {")
+         (kill-region (point) (save-excursion (search-forward "}") (backward-char) (point)))
+         (insert "\n")
+
+         (dolist (e errors)
+           (insert "\n")
+           (indent-according-to-mode)
+           (previous-line)
+           (insert (concat "MSG(" (replace-regexp-in-string "^FRES_ERR_" "" e) ");"))
+           (indent-according-to-mode)
+           (beginning-of-line)))))
+    (message "fres_error.c updated")))
+
+
+
+(provide 'frsh-forb)
+;;; frsh-forb.el ends here
diff --git a/src/frsh-include/.cvsignore b/src/frsh-include/.cvsignore
new file mode 100644 (file)
index 0000000..424c745
--- /dev/null
@@ -0,0 +1 @@
+*.h
diff --git a/src/frsh-include/Makefile.omk b/src/frsh-include/Makefile.omk
new file mode 100644 (file)
index 0000000..167e5a6
--- /dev/null
@@ -0,0 +1,12 @@
+include_HEADERS := $(notdir $(wildcard $(SOURCES_DIR)/*.h))
+
+ifeq ($(CONFIG_FRSH_FORB),y)
+UNWANTED_HEADERS += frsh_opaque_types.h
+endif
+UNWANTED_HEADERS += frsh_configuration_parameters.h
+include_HEADERS := $(filter-out $(UNWANTED_HEADERS),$(include_HEADERS))
+
+default_CONFIG := $(shell grep '^\#define FRSH' $(SOURCES_DIR)/frsh_configuration_parameters.h|sed -e 's/\#define \([^ ]*\) *\(.*\)/\1=\2/' -e 's/ //g' -e 's|//.*||' -e 's|/\*.*\*/||g')
+
+config_include_HEADERS = frsh_configuration_parameters.h
+frsh_configuration_parameters_DEFINES := $(shell echo '$(default_CONFIG)' | sed -e 's/\([^=]*\)=[^ ]*/\1/g')
diff --git a/src/frsh-include/dtm.h b/src/frsh-include/dtm.h
new file mode 100644 (file)
index 0000000..e8e27ea
--- /dev/null
@@ -0,0 +1,308 @@
+//----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politecnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org
+//
+//        The FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+// This file is part of DTM (Distributed Transaction Manager)
+//
+// DTM is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version.  DTM is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with DTM; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including DTM header files in a file,
+// instantiating DTM generics or templates, or linking other files
+// with DTM objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*!
+ * @file dtm.h
+ *
+ * @brief DTM API services
+ *
+ * This module contains the functions defined in the DTM API.
+ *
+ * @version 0.01
+ *
+ * @date 7-Sept-2007
+ *
+ * @author Michael Gonzalez Harbour <mgh@unican.es>
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ */
+
+#ifndef _DTM_H_
+#define _DTM_H_
+
+#include "frsh.h"
+
+typedef unsigned int trans_id_t;  /* 0 .. MX_TRANS-1 */
+
+typedef enum {
+        TRANS_UNKNOWN      =  0,
+        TRANS_IN_PROGRESS  =  1,
+        TRANS_ACTIVE       =  2,
+        TRANS_CANCELLED    =  3,
+} trans_status_t;
+
+/**
+ * dtm_resources_set_processor_vres()
+ *
+ * Set the virtual resource that will be used in the local processor by the
+ * manager thread of the agent of the DTM. This must be a valid virtual
+ * resource obtained form the negotiation of a contract.
+ *
+ **/
+
+extern int dtm_resources_set_processor_vres(const frsh_vres_id_t vres);
+
+/**
+ * dtm_resources_set_network_vres()
+ *
+ * Set the virtual resource that will be used by the local DTM agent to send
+ * messages to the specified destination address. This must be a valid virtual
+ * resource obtained from the negotiation of a network contract, and must be
+ * compatible with the current system topology. Multiple calls to this
+ * operation may be needed, one for each processing node that is connected
+ * directly.
+ *
+ **/
+
+extern int dtm_resources_set_network_vres(const frsh_resource_id_t  network,
+                                          const frsh_resource_id_t  dest,
+                                          const frsh_vres_id_t      vres);
+
+/**
+ * dtm_trans_init()
+ *
+ * Initialize a new transaction with the given name and maximum number of
+ * contracts. The newly created transaction will be initialized to contain
+ * no contracts.
+ *
+ **/
+
+extern int dtm_trans_init(const char          *name,
+                          const unsigned char num_contracts,
+                          trans_id_t          *trans);
+
+/**
+ * dtm_trans_add_contract()
+ *
+ * Add a reference to a contract to the given transaction together with
+ * the node in which that contract needs to be negotiated, and a boolean
+ * indicating whether or not the period needs to be synchronous with
+ * respect to other synchronous-period contracts in the transaction. Just
+ * the reference to the contract is copied, not the full contract information,
+ * and thus future changes to the contract may affect future negotiations
+ * or renegotiations.
+ *
+ **/
+
+extern int dtm_trans_add_contract(trans_id_t         trans,
+                                  frsh_contract_t    *contract,
+                                  frsh_resource_id_t node,
+                                  bool               is_synch_period);
+
+/**
+ * dtm_trans_remove_contract()
+ *
+ * Remove a contract, identified by its label, from the transaction.
+ *
+ **/
+
+extern int dtm_trans_remove_contract(trans_id_t trans,
+                                     const char *contract_label);
+
+/**
+ * dtm_trans_destroy()
+ *
+ * Destroy a transaction freeing any memory that was allocated to it at
+ * its creation.
+ *
+ **/
+
+extern int dtm_trans_destroy(trans_id_t trans);
+
+/**
+ * dtm_trans_num_contracts()
+ *
+ * Return the current number of contracts in a transaction.
+ *
+ **/
+
+extern int dtm_trans_num_contracts(trans_id_t trans, unsigned char *num);
+
+/**
+ * dtm_trans_get_contract()
+ *
+ * Given an index, return a reference to the contract stored in that index.
+ * This operation is used to iterate over the contracts of a transaction.
+ *
+ **/
+
+extern int dtm_trans_get_contract(trans_id_t      trans,
+                                  unsigned char   index,
+                                  frsh_contract_t **contract);
+
+/**
+ * dtm_trans_negotiate()
+ *
+ * Negotiate a transaction. This is a blocking call that will not return
+ * until the negotiation has been completed.
+ *
+ **/
+
+extern int dtm_trans_negotiate(trans_id_t trans);
+
+/**
+ * dtm_trans_cancel()
+ *
+ * Cancel a transaction, by cancelling all the virtual resources that were
+ * associated with it. Cancellation has to be invoked from the same node
+ * where the transaction was negotiated.
+ *
+ **/
+
+extern int dtm_trans_cancel(trans_id_t trans);
+
+/**
+ * dtm_trans_renegotiate()
+ *
+ * Renegotiate a transaction. This is a blocking call that will not return
+ * until the negotiation has been completed.
+ *
+ **/
+
+extern int dtm_trans_renegotiate(trans_id_t trans);
+
+/**
+ * dtm_priv_trans_search()
+ *
+ * Internal function that searches a transaction by its name. It returns
+ * true if the transaction exists and sets the parameter to the transaction
+ * handle.
+ *
+ * When allocate_if_miss equals true, it tries to allocate a new transaction
+ * if the transaction was not found with 0 contracts.
+ *
+ **/
+
+extern bool dtm_priv_trans_search(const char            *name,
+                                  trans_id_t            *trans,
+                                  const bool            allocate_if_miss);
+
+/**
+ * dtm_trans_get_status()
+ *
+ * Given a transaction name, get its status. This operation can be created
+ * in any node in the system. The status is an enumeration:
+ *
+ *      - unknown: the current node has not yet been involved in the transaction
+ *      - in_progress: the negotiation is in progress
+ *      - active: the transaction was successfully negotiated and is active
+ *      - cancelled: the transaction was cancelled
+ *
+ **/
+
+extern int dtm_trans_get_status(const char            *name,
+                                trans_status_t        *status);
+
+/**
+ * dtm_trans_wait_active()
+ *
+ * Given a transaction name, wait until it gets active. A handle to the
+ * transaction is obtained. A timeout may be specified.
+ *
+ **/
+
+extern int dtm_trans_wait_active(const char            *name,
+                                 const struct timespec *timeout,
+                                 trans_id_t            *trans);
+
+/**
+ * dtm_trans_get_vres()
+ *
+ * Given a transaction handle and a contract label, get the virtual resource
+ * associated with that contract in the local processor.
+ *
+ **/
+
+extern int dtm_trans_get_vres(trans_id_t         trans,
+                              const char         *contract_label,
+                              frsh_vres_id_t     *vres);
+
+/**
+ * dtm_trans_get_period()
+ *
+ * Get the current synchronous period of an active transaction, if any.
+ *
+ **/
+
+extern int dtm_trans_get_period(trans_id_t      trans,
+                                struct timespec *period);
+
+/**
+ * dtm_init()
+ *
+ * Initialize the distributed transaction manager in the local node.
+ * The stream Id to be used for DTM messages is specified as an argument.
+ * In first place, the operation creates all the necessary system resources
+ * (threads and communication endpoints) and binds them to the resources that
+ * were previously assigned locally to the DTM. Then, it performs the
+ * initialization process that synchronizes all the nodes, waiting until all
+ * of them are ready to work.
+ *
+ * TODO: The wait can be specified with a timeout,
+ * after which the operation would deallocate the allocated resources
+ * and return an error indication.
+ *
+ **/
+
+extern int dtm_init(frsh_stream_id_t stream);
+
+/**
+ * dtm_init_isdone()
+ *
+ * Query about whether the DTM has been initialized or not.
+ *
+ **/
+
+extern bool dtm_init_isdone(void);
+
+#endif // _DTM_H_
diff --git a/src/frsh-include/frsh.h b/src/frsh-include/frsh.h
new file mode 100644 (file)
index 0000000..f6347f3
--- /dev/null
@@ -0,0 +1,157 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_H_
+#define _FRSH_H_
+
+/**
+ * @file frsh.h
+ *
+ * Intended to be used by API clients to get the interface
+ * requirements.
+ *
+ * It is also used by the library files to enforce the interface
+ * headings.
+ *
+ * However it is NOT used by any of the FRSH include files to avoid
+ * having include deadlocks.
+ **/
+
+#include "fosa.h"
+
+#include "frsh_cpp_macros.h"
+
+#include "frsh_configuration_parameters.h"
+
+/* We include all the types because they are needed for the
+   frsh_contract_parameters_t */
+
+#include "frsh_core_types.h"
+#include "frsh_shared_objects_types.h"
+#include "frsh_spare_capacity_types.h"
+#include "frsh_hierarchical_types.h"
+#include "frsh_distributed_types.h"
+#include "frsh_implementation_specific_types.h"
+
+#include "frsh_core.h"
+#include "frsh_thread_attrs.h"
+#include "frsh_time.h"
+#include "frsh_implementation_specific.h"
+
+// Configure these modules by commenting out the appropiate lines
+
+#include "frsh_hierarchical.h"                 //
+#include "frsh_shared_objects.h"
+#include "frsh_dynamic_reclaiming.h"           //
+#include "frsh_spare_capacity.h"
+#include "frsh_distributed.h"                  //
+#include "frsh_feedback_control.h"
+#include "frsh_memory_management.h"
+#include "frsh_energy_management.h"
+
+#include "frsh_debug_and_trace.h"
+
+#ifndef FRSH_HIERARCHICAL_MODULE_SUPPORTED
+    #define FRSH_HIERARCHICAL_MODULE_SUPPORTED        0
+
+#endif  //FRSH_HIERARCHICAL_MODULE_SUPPORTED
+
+#ifndef FRSH_SHARED_OBJECTS_MODULE_SUPPORTED
+    #define FRSH_SHARED_OBJECTS_MODULE_SUPPORTED      0
+#endif  //FRSH_SHARED_OBJECTS_MODULE_SUPPORTED
+
+#ifndef FRSH_DYNAMIC_RECLAIMING_MODULE_SUPPORTED
+    #define FRSH_DYNAMIC_RECLAIMING_MODULE_SUPPORTED  0
+#endif  //FRSH_DYNAMIC_RECLAIMING_MODULE_SUPPORTED
+
+#ifndef FRSH_SPARE_CAPACITY_MODULE_SUPPORTED
+    #define FRSH_SPARE_CAPACITY_MODULE_SUPPORTED      0
+
+    //Return warnings if spare_capacity module is not included:
+
+    #define frsh_set_contract_reclamation_parameters  \
+      (contract, budget_max, period_min, granularity,\
+       utilization_set, quality,  importance)        \
+       ( FRSH_WRN_MODULE_NOT SUPPORTED )
+
+    #define frsh_get_contract_reclamation_parameters  \
+      (contract, budget_max, period_min, granularity,\
+       utilization_set, quality, importance)         \
+       ( FRSH_WRN_MODULE_NOT SUPPORTED )
+
+    #define frsh_request_change_quality_and_importance\
+      (server, new_importance, new_quality)          \
+       ( FRSH_WRN_MODULE_NOT SUPPORTED )
+
+    #define frsh_get_total_quality (server,total_quality)\
+       ( FRSH_WRN_MODULE_NOT SUPPORTED )
+
+#endif  //FRSH_SPARE_CAPACITY_MODULE_SUPPORTED
+
+#include <frsh_transaction.h>
+
+#endif // _FRSH_H_
diff --git a/src/frsh-include/frsh_configuration_parameters.h b/src/frsh-include/frsh_configuration_parameters.h
new file mode 100644 (file)
index 0000000..ab5ea8b
--- /dev/null
@@ -0,0 +1,375 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_configuration_parameters.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_CONFIGURATION_PARAMETERS_H_
+#define _FRSH_CONFIGURATION_PARAMETERS_H_
+
+#include <unistd.h>
+#include <limits.h>
+#include <frsh_cpp_macros.h>
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_configuration_parameters.h
+ *
+ * This file contains parameters that govern the capabilities of the
+ * FRescor ScHeduler.  They must be in concordance with the respective
+ * OS configuration.
+ **/
+
+
+/**
+ * @defgroup config Configuration Parameters
+ *
+ * Here we define global parameters that will have an important
+ * influence on FRSH behaviour.  They must also be coherent with the
+ * respective values in the underlaying OS.
+ *
+ * @{
+ **/
+
+
+/**
+ * This symbol specifies whether the scheduler will make a
+ * schedulability test of the requested contract or not
+ **/
+#define FRSH_ADMISSION_TEST_IS_ENABLED        true
+
+/**
+ * This symbol specifies whether the service thread will try to
+ * assign automatically the priorities of each vres
+ **/
+#define FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE true
+
+#ifdef ENABLE_FRSH_DISTRIBUTED_MODULE
+#define FRSH_DISTRIBUTED_MODULE_SUPPORTED true
+#else
+#define FRSH_DISTRIBUTED_MODULE_SUPPORTED false
+#endif
+
+/** This defines 1 resource_id value for systems that have only one
+    resource of a kind. **/
+#define FRSH_RESOURCE_ID_DEFAULT 0
+#define FRSH_CPU_ID_DEFAULT 0
+#define FRSH_NETWORK_ID_DEFAULT 0
+
+/**
+ * @defgroup internal Array size for memory optimization
+ * @ingroup config
+ *
+ * Tune these values for optimizing the amount of memory used by the
+ * implementation
+ *
+ * @{
+ **/
+
+/** Maximum number of accepted contracts (vres) **/
+#define FRSH_MAX_N_VRES                    25
+
+/** Maximum number of threads that may be scheduled by the framework **/
+#define FRSH_MAX_N_THREADS                    25
+
+/**
+ * Maximum number of critical sections that can be stored in a
+ * contract parameters object
+ **/
+#define FRSH_MAX_N_CRITICAL_SECTIONS          10
+
+/**
+ * Maximum number of memory areas that can be specified for a
+ * wite operation in a critical section
+ **/
+#define FRSH_MAX_N_MEMORY_AREAS               4
+
+/**
+ * Maximum number of utilization values (pairs of budget and period)
+ * that can be stored in a contract parameters object
+ **/
+#define FRSH_MAX_N_UTILIZATION_VALUES         5
+
+/** Number of importance levels for spare capacity allocation **/
+#define FRSH_N_IMPORTANCE_LEVELS     5
+
+/**
+ * Maximum number of synchronization objects
+ **/
+#define FRSH_MAX_N_SYNCH_OBJECTS              5
+
+/** Maximum number of shared objects **/
+#define FRSH_MAX_N_SHARED_OBJECTS             100
+
+/** Maximum number of send and receive endpoints in a single node **/
+#define FRSH_MAX_N_ENDPOINTS 10
+
+/** Maximum number of chars for a contract label **/
+#define FRSH_CONTRACT_LABEL_MAXLENGTH 15
+
+/*@}*/
+
+/**
+ * @defgroup schedandservice Scheduler and Service thread parameters
+ * @ingroup config
+ *
+ * The current implementation in MaRTE OS uses the Application-Defined
+ * Scheduling Interface (proposed to the POSIX standardization
+ * committee), to create a fixed-priority-based scheduler that
+ * operates under the rules of the FIRST scheduling framework.
+ *
+ * In this implementation there are two special threads:
+ *   - The application scheduler thread, that
+ *     implements the scheduler
+ *
+ *   - The service thread, that is in charge of
+ *     negotiating and renegotiating contracts
+ *     concurrently with the application
+ *
+ * The following symbols are necessary to adapt the application to the
+ * underlying fixed priority scheduler
+ *
+ * @{
+ **/
+
+/**
+ * Priority assigned to the application scheduler; it should be above
+ * the priorities of the application threads and of the service
+ * thread, and it should be at least 1 level below the maximum of the
+ *  system
+ **/
+#define FRSH_SCHEDULER_PRIORITY       (fosa_get_priority_max() -  FOSA_ADS_SCHEDULER_PRIO_DIFF)
+
+/**
+ * Real-time signal number reserved for the application scheduler to
+ * manage its timers.
+ **/
+#define FRSH_SCHEDULER_SIGNAL                 FRSH_SIGNAL_MIN
+
+
+
+/**
+ * The highest priority that can be assigned to an application thread,
+ * it should be defined as one level less than the
+ * FRSH_SCHEDULER_PRIORITY
+ **/
+#define FRSH_HIGHEST_THREAD_PRIORITY  (FRSH_SCHEDULER_PRIORITY-1)
+
+
+/**
+ * The lowest priority that can be assigned to an application thread,
+ * it should be at least 1 level above the minimum of the system
+ **/
+#define FRSH_LOWEST_THREAD_PRIORITY    ( fosa_get_priority_min() + 4)
+
+/**
+ * Each call to the functions that negotiate or renegotiate a contract
+ * or that change the quality and importance generates a request for
+ * the service thread that we call a service job.  This job will be
+ * pending in a queue until executed by the service thread.  The
+ * following symbol represents the maximum number of requests that can
+ * be simultaneously queued.
+ **/
+#define FRSH_MAX_N_SERVICE_JOBS  (FRSH_MAX_N_VRES * 2)
+
+
+/**
+ * In order to bound the background activity of the scheduler (i.e.,
+ * the admission tests necessary for the negotiation and
+ * re-negotiation of contracts), a service thread has been defined. It
+ * runs at a given priority level and has a budget and period
+ * assigned.
+ *
+ **/
+
+/** Initial period of the service thread (timespec) **/
+#define FRSH_SERVICE_THREAD_PERIOD_USECS 500000 /* 500 msecs */
+
+/** Initial budget of the service thread (timespec) **/
+#define FRSH_SERVICE_THREAD_BUDGET_USECS 1000 /* 1 msec */
+
+/**
+ * Initial priority of the service thread, it has to be lower than the
+ * FRSH_SCHEDULER_PRIORITY, and is set according to its period and the
+ * expected response times for reconfiguration or tunning of the
+ * system.
+ *
+ * If set to zero and FRSH_ADMISSSION_TEST_ENABLE is set to true then
+ * the priority will be assigned according to DMA rules.
+ **/
+//#define FRSH_SERVICE_THREAD_PRIORITY          (FRSH_LOWEST_THREAD_PRIORITY+1)
+#define FRSH_SERVICE_THREAD_PRIORITY          0
+
+
+/*@}*/
+
+
+/**
+ * @defgroup miscconfig Miscellaneous Config parameters
+ * @ingroup config
+ *
+ * @{
+ **/
+
+/**
+ * Maximum number of vres that can be simultaneusly waiting for
+ * being signaled in a synchronization object
+ **/
+#define FRSH_MAX_N_VRES_IN_SYNCH_OBJECT    4
+
+
+/**
+ * Maximum number of events that can be pending to be signaled in a
+ * synchronization object
+ **/
+#define FRSH_MAX_N_EVENTS_IN_SYNCH_OBJECT    100
+
+/**
+ * Maximum number of pending replenishments in each sporadic server
+ **/
+#define FRSH_MAX_N_PENDING_REPLENISHMENTS     25   //250
+
+
+/**
+ * Maximum number of target windows in a table driven schedule
+ **/
+#define FRSH_MAX_N_TARGET_WINDOWS             100
+
+/**
+ * The cpu time given by the round robin scheduler
+ * to the threads in the background (timespec)
+ **/
+#define FRSH_RR_SLICE_CPU_TIME_USECS 100000 // 0.1 sec
+
+/**
+ * This function must be supplied by the user to map the preemption
+ * level values given in the contracts for the vres, to priority
+ * values in the range that is allowed by the present implementation
+ * for application threads. The value returned by the function must
+ * fit in the interval defined by the constants:
+ * [FRSH_LOWEST_THREAD_PRIORITY, FRSH_HIGHEST_THREAD_PRIORITY]
+ **/
+int frsh_priority_map (unsigned long plevel);
+
+/**
+ * This symbol specifies the maximum number of chars that are stored
+ * of a given shared_object_id, so this is the maximum length used
+ * in comparisons
+ **/
+#define FRSH_MAX_SIZE_SHARED_OBJ_LABEL           15
+
+
+/** Maximum number of networks accesible from a node **/
+#define FRSH_MAX_N_NETWORK_IDS                1
+
+/**
+ * Maximum number of groups allocated at the same time
+ **/
+#define FRSH_MAX_N_GROUPS  3
+
+/**
+ * Maximum number of groups operations (neg, reneg, cancel) per group
+ **/
+#define FRSH_MAX_GROUP_OPS  25
+
+/**
+ * Default overheads of shared object protection mechanisms
+ * These values should be calibrated on each specific execution platform
+ */
+
+// fixed overhead for saving the environment and subsequently
+// aborting a critical section; units in nanoseconds
+
+#define FRSH_SO_FIXED_ABORT_OVHD        0
+
+
+// fixed overhead for copying a memory area, in nanoseconds
+
+#define FRSH_SO_FIXED_AREA_OVHD         0
+
+
+// variable overhead for copying a memory area; units in nanoseconds per kbyte
+
+#define FRSH_SO_NANOS_PER_KB            0
+
+
+/* Default memory pool's size in Kbytes */
+#define FRSH_DYNAMIC_MEMORY_POOL_SIZE 6670
+
+/**
+ * Maximum synchronized workload period number.  After this value any
+ * increments will be set to zero.
+ **/
+#define FRSH_MAX_SYNCHRONIZED_PERIOD_NUMBER LONG_MAX
+
+
+/*@}*/
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif /* _FRSH_CONFIGURATION_PARAMETERS_H_ */
+
diff --git a/src/frsh-include/frsh_core.h b/src/frsh-include/frsh_core.h
new file mode 100644 (file)
index 0000000..4681e05
--- /dev/null
@@ -0,0 +1,1600 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef _FRSH_CORE_H_
+#define _FRSH_CORE_H_
+
+
+/**
+ * @file frsh_core.h
+ **/
+
+
+#include <time.h>
+#include <sys/types.h>
+
+#include "frsh_core_types.h"
+#include "frsh_spare_capacity.h"
+
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @defgroup core Core module
+ *
+ * This module includes the basic functions and services that are
+ * provided by any FRSH implementation. This module includes basic type
+ * definitions, and functions to
+ *
+ * - create a contract and initialize it
+ * - set/get the basic parameters of a contract
+ * - negotiate a service contract, obtaining a vres id
+ * - create and bind threads to vres
+ * - create/destroy a synchronization object
+ * - manage bounded workloads
+ *
+ **/
+
+
+//////////////////////////////////////////////////////////////////////
+//           INITIALIZATION SERVICES
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup initialization Initialization services
+ * @ingroup core
+ *
+ * These functions need to be called before doing any FRSH operation
+ * (including contract initialization).
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_init()
+ *
+ * We cannot call any frsh functions before frsh_init. After calling
+ * frsh_init, the main will be executing in the background. Then, it
+ * can do the negotiations and create new threads if needed.  The
+ * second time this function is called it fails.
+ *
+ * @return 0 if no error. \n
+ *  FRSH_ERR_SYSTEM_ALREADY_INITIALIZED : if the function has already
+ *                                        been called before\n
+ *  .
+ *  It may also return any of the errors that may be returned by the
+ *  underlying operating system primitives required to perform the
+ *  FRSH system start up
+ *
+ **/
+int frsh_init();
+
+/**
+ * frsh_destroy()
+ *
+ * Reverts the efect of frsh_init().
+ */
+void frsh_destroy();
+
+/*@}*/
+
+
+/////////////////////////////////////////////////////////////
+//                       CONTRACT PARAMETERS
+/////////////////////////////////////////////////////////////
+/**
+ * @defgroup contract Contract Creation and Initialization.
+ * @ingroup core
+ *
+ * These functions are used to create and initialize a contract, and
+ * set its parameters.
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_contract_init()
+ *
+ * The operation receives a pointer to a contract object
+ * and initializes it, setting it to the default values.
+ *
+ * The default values are:
+ *
+ * - resource_id               => 0
+ * - ressource_type            => FRSH_CRT_PROCESSOR
+ * - contract_label               => ""
+ * - budget_min                => {0,0};
+ * - period_max                => {0,0};
+ * - budget_max                => {0,0};
+ * - period_min                => {0,0};
+ * - workload                  => FRSH_WT_INDETERMINATE
+ * - d_equals_t                => true
+ * - contract_type             => FRSH_CT_REGULAR;
+ * - deadline                  => {0,0};
+ * - budget_overrun_signal => 0;  (signal number)
+ * - budget_overrun_siginfo  => {0, NULL};
+ * - deadline_miss_signal  => 0;  (signal number)
+ * - deadline_miss_siginfo   => {0, NULL};
+ *
+ * - granularity               => DEFAULT_GRANULARITY;
+ * - utilization_set;          => size = 0
+ * - quality                   => DEFAULT_QUALITY;    (range 0..100)
+ * - importance                => DEFAULT_IMPORTANCE; (range 1..5)
+ * - preemption_level          => 0; (range 1..2**32-1)
+ * - critical_sections;        => size = 0
+ *
+ * - sched_policy              => DEFAULT_SCHED_POLICY (FRSH_NONE)
+ *
+ * @param     contract the pointer to the contract variable.
+ *
+ * @return 0 if no error \n
+ *     FRSH_ERR_BAD_ARGUMENT :  contract is NULL
+ *
+ **/
+int frsh_contract_init(frsh_contract_t *contract);
+
+
+/**
+ * frsh_contract_destroy()
+ *
+ * The operation deallocates all memory which might be allocated for
+ * the contract.
+ *
+ * @param contract the pointer to the contract variable.
+ **/
+void frsh_contract_destroy(frsh_contract_t *contract);
+
+
+/**
+ * frsh_contract_set_basic_params()
+ *
+ * The operation updates the specified contract parameters object by
+ * setting its budget, period, workload and type to the specified
+ * input parameters. (Note: the workload is a basic parameter because
+ * bounded tasks are triggered by the scheduler (see the
+ * frsh_timed_wait() and frsh_synchobj_wait* operations), while
+ * indeterminate tasks are not; therefore, their programming model is
+ * quite different).
+ *
+ * @param contract     the pointer to the contract object
+ * @param[in] budget_min   the minimum budget for the contract
+ * @param[in] period_max   the maximum period for the contract
+ * @param[in] workload     the kind of workload (can be FRSH_WT_BOUNDED,
+ *                            FRSH_WT_INDETERMINATE or FRSH_OVERHEAD)
+ * @param[in] contract_type can be FRSH_CT_REGULAR,
+ *                                 FRSH_CT_BACKGROUND, FRSH_CT_DUMMY.
+ *
+ * @return 0 if no error \n
+ *    FRSH_ERR_BAD_ARGUMENT :  if any of the pointers is NULL
+ *    or if only one of the time values is 0, and also if the
+ *    workload or the contract type values are unknown in the
+ *    enumerations.
+ **/
+int frsh_contract_set_basic_params
+  (frsh_contract_t *contract,
+   const frsh_rel_time_t      *budget_min,
+   const frsh_rel_time_t      *period_max,
+   const frsh_workload_t      workload,
+   const frsh_contract_type_t contract_type);
+
+/**
+ * frsh_contract_get_basic_params()
+ *
+ * This operation obtains from the specified contract object its
+ * budget, period, and workload, and copies them to the places pointed
+ * to by the corresponding output parameters.
+ *
+ * @param[in] contract   the pointer to the contract object
+ * @param[out] budget_min pointer to preallocated space
+ * @param[out] period_max pointer to preallocated space
+ * @param[out] workload pointer to preallocated space
+ * @param[out] contract_type pointer to preallocated space
+ *
+ * @return   0 if no error \n
+ *       FRSH_ERR_BAD_ARGUMENT :  if one of the contract or
+ *                                    pointers is NULL.
+ *
+ **/
+int frsh_contract_get_basic_params
+  (const frsh_contract_t *contract,
+   frsh_rel_time_t  *budget_min,
+   frsh_rel_time_t  *period_max,
+   frsh_workload_t   *workload,
+   frsh_contract_type_t *contract_type);
+
+/**
+ * frsh_contract_set_resource_and_label()
+ *
+ * Specify resource_id and type, and the contract label. Otherwise
+ * default values will apply. If the contract label is too long it is truncated
+ *
+ * @return   0 if no error \n
+ *       FRSH_ERR_BAD_ARGUMENT :  if the contract pointer is NULL.
+ **/
+int frsh_contract_set_resource_and_label
+  (frsh_contract_t *contract,
+   const frsh_resource_type_t resource_type,
+   const frsh_resource_id_t resource_id,
+   const char *contract_label);
+
+
+/**
+ * frsh_contract_get_resource_and_label()
+ *
+ * Obtain the resource_id and type, and the contract label.
+ *
+ * @return   0 if no error \n
+ *       FRSH_ERR_BAD_ARGUMENT :  if the contract or the contract_label
+ *                                 pointer is NULL.
+ **/
+int frsh_contract_get_resource_and_label
+  (const frsh_contract_t *contract,
+   frsh_resource_type_t *resource_type,
+   frsh_resource_id_t *resource_id,
+   char *contract_label);
+
+
+/**
+ * frsh_contract_set_timing_reqs()
+ *
+ * The operation updates the specified contract object, specifying
+ * additional time-related requirements.
+ *
+ * @param  contract The pointer to the contract object
+ *
+ * @param [in] d_equals_t It is a boolean value, set to true (1) if
+ *                        we want to specify a deadline different from
+ *                        the period  for the contract.
+ * @param [in] deadline  If the previous parameter is set to true,
+ *                       this parameter is ignored (the contract value
+ *                       will be NULL_DEADLINE internally). Otherwise, it
+ *                       contains the desired deadline value.
+ *
+ * @return  0 if successful\n
+ *     FRSH_ERR_BAD_ARGUMENT :  if contract is NULL \b or \n
+ *      (d_equals_t is true and  deadline is not FRSH_NULL_DEADLINE) \b or \n
+ *      (budget_overrun_signal is not a valid signal)  \b or \n
+ *      (deadline_miss_signal is not a valid signal) \b or \n
+ *      (d_equals_t is false but (deadline is FRSH_NULL_DEADLINE or its value
+ *                                is grater than the contract's maximum period))
+ *
+ **/
+int frsh_contract_set_timing_reqs
+  (frsh_contract_t *contract,
+   const bool                   d_equals_t,
+   const frsh_rel_time_t        *deadline);
+
+/**
+ * frsh_contract_get_timing_reqs()
+ *
+ * The operation obtains the corresponding input parameters from the
+ * specified contract object. If d_equals_t is true, the deadline will
+ * be set to FRSH_NULL_DEADLINE.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if contract is NULL
+ *
+ **/
+int frsh_contract_get_timing_reqs
+  (const frsh_contract_t *contract,
+   bool                    *d_equals_t,
+   frsh_rel_time_t         *deadline);
+
+
+/*@}*/
+
+//////////////////////////////////////////////////////////////////
+//                 SYNCHRONIZATION OBJECTS
+//////////////////////////////////////////////////////////////////
+/**
+ * @defgroup synch  Synchronization objects
+ * @ingroup core
+ *
+ * Synchronisation objects provide an alternative to timers for
+ * bounded-workload vres to signal the end of their current job and
+ * return their remaining budget to FRSH.
+ *
+ * Instead of asking to be reactivated based on an absolute time, they
+ * queue themselves in a synchronisation object and will wait there
+ * until another vres (bounded-workload or indeterminate-workload)
+ * wakes them up with a signal call the earliest at the beginning of
+ * the next period.
+ *
+ * Indeterminate-workload vres cannot queue themselves here because
+ * they don't have any budget to return.  However they can signal on
+ * the objects to activate a waiting workload vres.
+ *
+ * For classical signal/wait synchronisation paradigms the application
+ * must use whatever mechanism the underlying OS provides.
+ *
+ * In the future we may add a broadcast operation that would signal a
+ * group of synchronization objects. We have not included a broadcast
+ * service in this version because it can be easily created by the
+ * user by signalling individual synchronization objects inside a
+ * loop.
+ *
+ * Notice that for synchronization objects there is no naming service
+ * like in shared objects because tasks that use synchronization are
+ * not developed independently, as they are closely coupled.
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_synchobj_create()
+ *
+ * This operation creates and initializes a synchronization object
+ * variable managed by the scheduler, and returns a handle to it in
+ * the variable pointed to by synch_handle.
+ *
+ * @param[out]  synch_handle pointer to the variable that will contain
+ *                  the handle to the newly created synchronization object
+ *
+ * @return      0 if the operation is succesful
+ *              FRSH_ERR_TOO_MANY_SYNCH_OBJS if the number of synchronization
+ *              objects in the system has already exceeded the maximum
+ *
+ *   FRSH_ERR_TOO_MANY_SYNCH_OBJS : if the number of synchronization
+ *      objects in the system has already exceeded the maximum\n
+ *   .
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under FRSH\n
+ *   .
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
+ *
+ **/
+int frsh_synchobj_create
+    (frsh_synchobj_handle_t *synch_handle);
+
+
+/**
+ * frsh_synchobj_destroy()
+ *
+ * This operation destroys the synchronization object (created by a
+ * previous call to frsh_synchobj_create) that is referenced by the
+ * synch_handle variable. After calling this operation, the
+ * synch_handle variable can not be used until it is initialized again
+ * by a call to frsh_synchobj_create.
+ *
+ * @param synch_handle the handle to the synchronization object
+ *            to be destroyed
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if synch_handle is 0\n
+ *   FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid\n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *                            scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *                            running
+ *
+ * @sa frsh_synchobj_create
+ **/
+int frsh_synchobj_destroy
+    (const frsh_synchobj_handle_t synchobj_handle);
+
+/**
+ * frsh_synchobj_wait()
+ *
+ * This operation is invoked by threads associated with bounded
+ * workload vres to indicate that a job has been completed (and
+ * that the scheduler may reassign the unused capacity of the current
+ * job to other vres).
+ *
+ * As a difference with frsh_timed_wait(), here the vres
+ * specifies to be awakened by the arrival of a signal operation
+ * instead of at a precise point of time.
+ *
+ * This function can also be called to schedule the first job of a
+ * recently created vres and make it start when a signal operation
+ * has been sent from another thread.
+ *
+ * The vres' budget will be made zero for the remainder of the vres'
+ * period, and FRSH will not replenish it until an event has been
+ * notified to the synchronisation object by another vres.
+ *
+ * It can happen that the synchronisation object has notification
+ * events queued from the past, in this case one of the events is
+ * dequeued immediately and the vres won't have to wait for another
+ * one.
+ *
+ * At the time of reception of a notification event (wether in the
+ * future or in the past), all pending budget replenishments (if any)
+ * are made effective. Once the vres has a positive budget and the
+ * scheduler schedules the calling thread again, the call returns and
+ * the vres continues executing.
+ *
+ * If the synchronisation object is destroyed while the vres was
+ * waiting on it, the vres will be awaken and the function will
+ * return with a code FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE
+ *
+ * Except for those parameters equal to NULL pointers, the system
+ * reports the current period and budget for the current job, it informs
+ * if the deadline of the previous job was missed or not, and whether the
+ * budget of the previous job was overrun or not.
+ *
+ * In a system with hierarchical scheduling, since this call makes the
+ * budget of the current period zero, the other threads in the same
+ * vres are not run. As mentioned above, only when the call finishes
+ * the budget may be replenished.
+ *
+ * @param synch_handle   Synchronisation object upon which the vres
+ *                       will be waiting.
+ * @param next_budget[out]  Upon return of this function, the variable
+ *                          pointed by this function will be equal to
+ *                                     the current vres budget. If this parameter is
+ *                                     set to NULL, no action is taken
+ * @param next_period[out]  The vres period upon return (ignored if NULL).
+ * @param was_deadline_missed Upon return whether the deadline was
+ *                           missed in the previous period.
+ * @param was_budget_overran
+ *
+ *
+ * @return 0 if success \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *               running \n
+ *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ *     main scheduler \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
+ *     under FRSH \n
+ *   FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
+ *            vres bound to it \n
+ *   FRSH_ERR_BAD_ARGUMENT : if synch_handle is 0 \n
+ *   FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the synch_handle is not
+ *          valid or was destroyed while the vres was waiting on it. \n
+ *   FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
+ *     is not FRSH_BOUNDED
+ *
+ **/
+int frsh_synchobj_wait
+  (const frsh_synchobj_handle_t  synch_handle,
+   frsh_rel_time_t               *next_budget,
+   frsh_rel_time_t               *next_period,
+   bool                          *was_deadline_missed,
+   bool                          *was_budget_overran);
+
+
+/**
+ * frsh_synchobj_wait_with_timeout()
+ *
+ * This call is the same as frsh_synchobj_wait() but with an extra
+ * absolute timeout. The timed_out argument, indicates whether the
+ * function returned because of the expiration of the timeout or not.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the synch_handle is not
+ *        valid \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *        running \n
+ *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ *     main scheduler \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
+ *     under FRSH \n
+ *   FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
+ *     vres bound to it \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if the synch_handle given is not valid or the
+ *     abs_timeout argument is NULL or its value is in the past\n
+ *   FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
+ *     is not FRSH_BOUNDED
+ *
+ **/
+int frsh_synchobj_wait_with_timeout
+  (const frsh_synchobj_handle_t  synch_handle,
+   const frsh_abs_time_t         *abs_timeout,
+   bool                          *timed_out,
+   frsh_rel_time_t               *next_budget,
+   frsh_rel_time_t               *next_period,
+   bool                          *was_deadline_missed,
+   bool                          *was_budget_overran);
+
+/**
+ * frsh_synchobj_signal()
+ *
+ * This function sends a notification event to the synchronization object
+ * specified as parameter. If there is at least one vres waiting on
+ * the synchronization object, it is awaken. If more than one vres
+ * are waiting, just one of them is awaken. However, which one is
+ * awaken is implementation dependent. If no vres is waiting on the
+ * synchronization object, the notification event is queued.
+ *
+ * @param [in] synch_handle the handle of the synchronization object to
+ *                 notify.
+ *
+ * @return 0 if no error \n
+ *    FRSH_ERR_BAD_ARGUMENT :  if synch_handle is 0 \n
+ *    FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid \n
+ *    FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *            scheduled under FRSH \n
+ *    FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *            running \n
+ *    FRSH_ERR_TOO_MANY_EVENTS_IN_SYNCH_OBJ : if the number of events stored
+ *            in the synchronization object reaches the maximum defined in the
+ *            configuration parameter header file
+ *
+ * @sa frsh_synchobj_wait, frsh_synchobj_wait_with_timeout
+ **/
+int frsh_synchobj_signal
+    (const frsh_synchobj_handle_t synch_handle);
+
+/**
+ * frsh_timed_wait()
+ *
+ * This operation is invoked by threads associated with bounded
+ * workload vres to indicate that a job has been completed (and
+ * that the scheduler may reassign the unused capacity of the current
+ * job to other vres). It is also invoked when the first job of
+ * such threads has to be scheduled.
+ *
+ * As an effect, the system will make the current vres's budget zero
+ * for the remainder of the vres's period, and will not replenish
+ * the budget until the specified absolute time.  At that time, all
+ * pending budget replenishments (if any) are made effective. Once the
+ * vres has a positive budget and the scheduler schedules the
+ * calling thread again, the call returns and at that time, except for
+ * those parameters equal to NULL pointers, the system reports the
+ * current period and budget for the current job, whether the deadline
+ * of the previous job was missed or not, and whether the budget of
+ * the previous job was overrun or not.
+ *
+ * In a system with hierarchical scheduling, since this call makes the
+ * budget zero, the other threads in the same vres are not run. As
+ * mentioned abobe, only when the call finishes the budget may be
+ * replenished.
+ *
+ * @param [in] abs_time     absolute time at which the budget will be
+ *                          replenished
+ *
+ * @param [out] next_budget upon return of this function, the variable
+ *                          pointed by this function will be equal to
+ *                         the current vres budget. If this parameter is
+ *                         set to NULL, no action is taken.
+ *
+ * @param [out] next_period upon return of this function, the variable
+ *                          pointed by this function will be equal to
+ *                         the current vres period. If this parameter is
+ *                         set to NULL, no action is taken.
+ *
+ * @param [out] was_deadline_missed upon return of this function, the
+ *                          variable pointed by this function will be
+ *                          equal to true if the previous vres deadline
+ *                         was missed, to false otherwise. If this
+ *                          parameter is set to NULL, no action is
+ *                          taken.
+ *
+ * @param [out] was_budget_overrun upon return of this function, the
+ *                          variable pointed by this function will be
+ *                          equal to true if the previous vres budget was
+ *                          overrun, to false otherwise. If this
+ *                          parameter is set to NULL, no action is
+ *                          taken.
+ *
+ * @return  0 if the operation is successful \n
+ *   FRSH_ERR_TIME_SPEC_IN_THE_PAST if the absolute time specification
+ *            is in the past. \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong
+ *             or not running \n
+ *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ *                                    main scheduler \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling
+ *                      thread is not scheduled under FRSH \n
+ *   FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
+ *     vres bound to it \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if abs_time is NULL \n
+ *   FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
+ *     is not FRSH_BOUNDED
+ *
+ *
+ * @sa frsh_synchobj_wait, frsh_synchobj_wait_with_timeout
+ **/
+int frsh_timed_wait
+  (const frsh_abs_time_t *abs_time,
+   frsh_rel_time_t       *next_budget,
+   frsh_rel_time_t       *next_period,
+   bool                  *was_deadline_missed,
+   bool                  *was_budget_overran);
+
+
+
+/**
+ * frsh_vresperiod_wait()
+ *
+ * Suspend the calling thread until the start of the specified virtual
+ * resource period of a vres_id, for a synchronized workload.
+ *
+ * Virtual resource periods are numbered. The number of the current
+ * period can be obtained through the frsh_vres_get_period_number()
+ * operation.
+ **/
+int frsh_vresperiod_wait(unsigned long period_num,
+                         frsh_rel_time_t       *next_budget,
+                         frsh_rel_time_t       *next_period,
+                         bool                  *was_deadline_missed,
+                         bool                  *was_budget_overran);
+
+
+/**
+ * frsh_vres_get_period()
+ *
+ * Return the current period number, for a virtual resource of
+ * synchronized workload.
+ **/
+int frsh_vres_get_period_number
+   (const frsh_vres_id_t vres,
+    long *period_num);
+
+
+
+
+/*@}*/
+
+///////////////////////////////////////////////////////////////////
+//                 CONTRACT NEGOCIATION OPERATIONS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup negotiate Negotiate contract functions
+ * @ingroup core
+ *
+ * The following functions are used to negotiate contracts and thus
+ * creating vres which are the execution image of a contract.
+ * Besides, these functions allow to assign and unassign threads to
+ * vres.
+ *
+ * In the case of more than one thread per vres please refer to the
+ * hierarchical module.
+ *
+ * @{
+ **/
+
+
+
+/**
+ * frsh_contract_negotiate()
+ *
+ * The operation negotiates a contract and if accepted it will return
+ * a vres_id.  It will also check that the given contract_label is unique
+ * within the node.
+ *
+ * If the on-line admission test is enabled, it determines whether the
+ * contract can be admitted or not based on the current contracts
+ * established in the system. Then it creates the vres and
+ * recalculates all necessary parameters for the contracts already
+ * present in the system.
+ *
+ * This is a potentially blocking operation, it returns when the
+ * system has either rejected the contract, or admitted it and made it
+ * effective. No thread is bound to the newly created vres, which
+ * will be idle until a thread is bound to it via frsh_thread_bind()
+ * or frsh_thread_create_and_bind().
+ *
+ * This operation can only be executed by threads that are already
+ * bound to an active vres and therefore are being scheduled by the
+ * frsh scheduler.
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_CONTRACT_REJECTED:  The contract is not accepted.\n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *                running \n
+ *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ *     main scheduler \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
+ *     under FRSH scheduler \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if the contract or vres arguments are NULL \n
+ *   FRSH_ERR_TOO_MANY_VRES : if there is no space for more vres
+ *     (the maximum number of them is already reached) \n
+ *   FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS : contract_label is not unique.
+ *
+ **/
+int frsh_contract_negotiate
+  (const frsh_contract_t *contract,
+   frsh_vres_id_t        *vres);
+
+/**
+ * frsh_thread_create_and_bind()
+ *
+ * This operation creates a thread and binds it to an existing vres.
+ *
+ * This is the preferred way to add threads to the application because
+ * we make sure that the thread won't become unbound.
+ *
+ * The vres must not have any thread binded to it.  If you want to
+ * bind more than one thread to the vres you must use the
+ * hierarchical module.
+ *
+ * The frsh_thread_attr_t parameter is overwritten as necessary to
+ * introduce the adequate scheduling policy and priority,  according
+ * to the preemption level given in the contract and the
+ * frsh_priority_map() function defined by the user.
+ *
+ * @param[in] vres_id       vres with which the thread will be bound.
+ * @param[out] thread         frsh_thread_id returned by the system.
+ * @param attr         pthread_attr taken and maybe corrected
+ *                                by the system.  Ignored if NULL
+ * @param[in] thread_code     Thread function (void func(void *) )
+ *                                that will constitute the main of the
+ *                                thread.
+ * @param[in] arg             Argument for data to be passed at the
+ *                            thread. Set to NUL if you don't want
+ *                            to do anything like this.
+ *
+ * @return  0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the contract or vres arguments are
+ *               NULL \n
+ *   FRSH_ERR_CONTRACT_REJECTED : if the contract is rejected. \n
+ *   .
+ *   It may also return all the errors that may be returned by the
+ *     fosa_thread_create() function call
+ *
+ **/
+int frsh_thread_create_and_bind
+  (const frsh_vres_id_t vres,
+   frsh_thread_id_t     *thread,
+   frsh_thread_attr_t   *attr,
+   frsh_thread_code_t   thread_code,
+   void                 *arg);
+
+
+/**
+ * frsh_thread_create_in_background()
+ *
+ * This function creates a "background contract" that does not need to
+ * be negotiated, creates a threads and binds to the new vres.
+ *
+ * This method is suggested as a way to initate components and
+ * plugins.  The event that triggers the component activation should
+ * arrive to an application thread that could use this function to
+ * create a thread used in its initialisation.
+ *
+ * The attribute parameter is overwritten as necessary to introduce
+ * the adequate scheduling policy and priority.
+ *
+ * @param[in]  thread_code   Function to be executed by the new
+ *                           thread.
+ * @param[in]  thread_arg    General pointer that will be passed to
+ *                           the new thread as initialisation data.
+ * @param attr               Pthread attribute with thread params
+ * @param[in]  contract_label   Contract label for the new vres.
+ * @param[out] thread_id     Id of the new thread.
+ * @param[out] vres_id       vres_id of the new vres.
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT : Any problems with the argument \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is
+ *               not scheduled under FRSH \n
+ *   FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS : contract_label is not unique \n
+ *   FRSH_ERR_TOO_MANY_VRES : if there is no space for more vres
+ *     (the maximum number of them is already reached)
+ *
+ **/
+int frsh_thread_create_in_background
+    (frsh_thread_code_t thread_code,
+     const void *thread_arg,
+     const char *contract_label,
+     frsh_thread_attr_t *attr,
+     frsh_thread_id_t *thread_id,
+     frsh_vres_id_t *vres_id);
+
+
+
+/**
+ * frsh_thread_join_in_background()
+ *
+ * This function is aimed for external threads to join FRSH in the
+ * least disturbing possible mode.
+ *
+ * Upon calling this function by a thread which has been created
+ * natively in the OS, it joins the framework and gets inmediately
+ * bound to an on-the-fly generated background contract.
+ *
+ * In order to gain a higher priority then it can renegotiate a
+ * contract for its vres with the needed parameters.
+ *
+ * @param[in] resource_id:   Resource (CPU) in which the vres will
+ *                           be associated.
+ *
+ * @param[in] resource_type: Resource type (should be CPU) for the
+ *                           contract.
+ *
+ * @param[in] label:         Label to be added to the contract.
+ *
+ * @param[out] vres_id:      Resulting vres_id from the on-the-fly
+ *                           generated background contract.
+ *
+ * @return  0 if successful\n
+ *          FRSH_ERR_NOT_CONTRACTED_VRES if the thread is already
+ *          bound to a vres.
+ **/
+int frsh_thread_join_in_background(frsh_resource_id_t resource_id,
+                                   frsh_resource_type_t resource_type,
+                                   const char *label,
+                                   frsh_vres_id_t *vres_id);
+
+
+
+/**
+ * frsh_thread_bind()
+ *
+ * This operation associates a thread with a vres, which means that
+ * it starts consuming the vres's budget  and is executed according
+ * to the contract established for that vres. If the thread is
+ * already bound to another vres, it is effectively unbound from it
+ * and bound to the specified one.
+ *
+ * It fails if the vres's policy is different than FRSH_NONE, or if
+ * there is already a thread bound to this vres.  In order to bind
+ * more than one vres to the same thread you must use the
+ * hierarchical module.
+ *
+ * Implementation dependent issue: In order to allow the usage of
+ * application defined schedulers, the given thread must not have the
+ * scheduling policy SCHED_APP and at the same time be attached to an
+ * application scheduler different than the frsh scheduler.
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ *     main scheduler \n
+ *   FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
+ *     an application defined scheduler different than the frsh
+ *     scheduler \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the vres value does not complain with the
+ *     expected format or valid range or the given thread does not
+ *     exist \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the referenced vres is not
+ *      valid \n
+ *   FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload
+ *     of the vres is FRSH_OVERHEAD \n
+ *   FRSH_ERR_ALREADY_BOUND : if the given vres has a thread already
+ *     bound
+ *
+ **/
+int frsh_thread_bind
+  (const frsh_vres_id_t   vres,
+   const frsh_thread_id_t thread);
+
+
+/**
+ * frsh_thread_unbind()
+ *
+ * This operation unbinds a thread from a vres.  Since threads with
+ * no vres associated are not allowed to execute, they remain in a
+ * dormant state until they are either eliminated or bound again.
+ *
+ * If the thread is inside a critical section the effects of this call
+ * are deferred until the critical section is ended
+ *
+ * Implementation dependent issue: in the implementation with an
+ * application scheduler, the thread is still attached to the frsh
+ * scheduler, but suspended.
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ *     main scheduler \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist \n
+ *   FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled
+ *     under FRSH \n
+ *   FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
+ *     an application defined scheduler different than the frsh
+ *     scheduler \n
+ *   FRSH_ERR_NOT_BOUND : if the given thread does not have a valid
+ *     vres bound to it
+ **/
+int frsh_thread_unbind(const frsh_thread_id_t thread);
+
+/**
+ * frsh_vres_set_notification()
+ *
+ * This function setups notification signals for CPU vres. It is
+ * necessary to call this function before bounding the thread to the
+ * vres.
+ * 
+ * @param [in] budget_overrun_signal contains the number of the signal
+ *                that must be raised if the budget of the vres is
+ *                overrun by the thread.
+ *                If the value of this parameter is FRSH_NULL_SIGNAL, no signal will
+ *                be raised.
+ * @param [in] budget_overrun_siginfo contains the value that will be
+ *               passed to the signal "catcher" when the signal is raised.
+ *               This parameters is not used if the budget_overrun_signal
+ *               parameter is set to FRSH_NULL_SIGNAL.
+ * @param [in] deadline_miss_signal contains the number of the
+ *               signal that must be raised if the deadline of the
+ *               vres is missed. If the value of this parameter is
+ *               FRSH_NULL_SIGNAL, no signal is raised.
+ * @param [in] deadline_miss_siginfo contains the value that will be
+ *                passed to the signal "catcher" when the signal is
+ *                raised.  This parameter is not used if the
+ *                deadline_signal parameter is set to NULL_SIGNAL
+ **/
+int frsh_vres_set_notification(
+       frsh_vres_id_t vres,
+       const frsh_signal_t          budget_overrun_signal,
+       const frsh_signal_info_t     budget_overrun_siginfo,
+       const frsh_signal_t          deadline_miss_signal,
+       const frsh_signal_info_t     deadline_miss_siginfo);
+
+/**
+ * frsh_thread_get_vres_id()
+ *
+ * This operation stores the Id of the vres associated with the
+ * specified thread in the variable pointed to by vres. It returns
+ * an error if the thread does not exist, it is not under the control
+ * of the scheduling framework, or is not bound.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled
+ *     under FRSH \n
+ *   FRSH_ERR_NOT_BOUND : if the given thread does not have a valid
+ *     vres bound to it \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist or the
+ *     vres argument is NULL
+ *
+ **/
+int frsh_thread_get_vres_id(const frsh_thread_id_t       thread,
+                    frsh_vres_id_t *vres_id);
+
+/**
+ * frsh_vres_get_priority()
+ *
+ * This operation stores the priority currently associated
+ * with the specified vres in the variable pointed to by
+ * priority. It returns an error if the vres_id is not recognised.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if the contract argument is NULL or the value
+ *     of the vres argument is not in range \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *        running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES: if the vres of the calling thread
+ *     has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_priority
+     (frsh_vres_id_t            vres_id,
+      int *priority);
+
+/**
+ * frsh_vres_get_contract()
+ *
+ * This operation stores the contract parameters currently associated
+ * with the specified vres in the variable pointed to by
+ * contract. It returns an error if the vres_id is not recognised.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if the contract argument is NULL or the value
+ *     of the vres argument is not in range \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *        running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES: if the vres of the calling thread
+ *     has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_contract
+  (const frsh_vres_id_t vres,
+    frsh_contract_t *contract);
+
+/**
+ * frsh_resource_get_vres_from_label()
+ *
+ * This operation retrieves the vres_id whose contract_label
+ * corresponds to the parameter in the resource_id and resource_type
+ * specified.
+ *
+ * The contract label must refer to a contract negotiated
+ * in the same processing node in which the call is being
+ * made. Otherwise an error is returned.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if the contract argument is NULL or the
+ *     contract_label is NULL \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *     running \n
+ *   FRSH_ERR_CONTRACT_LABEL_UNKNOWN: if the contract_label is not known
+ **/
+int frsh_resource_get_vres_from_label
+  (const char *contract_label,
+   const frsh_resource_type_t resource_type,
+   const frsh_resource_id_t resource_id,
+   frsh_vres_id_t *vres);
+
+
+
+/**
+ * frsh_contract_cancel()
+ *
+ * The operation eliminates the specified vres
+ * and recalculates all necessary parameters for the contracts
+ * remaining in the system. This is a potentially blocking operation;
+ * it returns when the system has made the changes effective.
+ *
+ * Note that the thread is not eliminated.  We leave the application
+ * the option to either freeze it for a later use or bind it to
+ * another vres.
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if the value of vres is not in range \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *     running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ *     has been cancelled or it is not valid
+ *
+ **/
+int frsh_contract_cancel (const frsh_vres_id_t vres);
+
+
+/**
+ * frsh_contract_renegotiate_sync()
+ *
+ * The operation renegotiates a contract for an existing vres. If
+ * the on-line admission test is enabled it determines whether the
+ * contract can be admitted or not based on the current contracts
+ * established in the system. If it cannot be admitted, the old
+ * contract remains in effect and an error is returned. If it can be
+ * admitted, it recalculates all necessary parameters for the
+ * contracts already present in the system and returns zero. This is a
+ * potentially blocking operation; it returns when the system has
+ * either rejected the new contract, or admitted it and made it
+ * effective.
+ *
+ *  @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if the new_contract argument is NULL or the
+ *     value of the vres argument is not in range \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *     running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ *     has been cancelled or it is not valid \n
+ *   FRSH_ERR_CONTRACT_REJECTED : if the renegotiation fails
+ *
+ **/
+int frsh_contract_renegotiate_sync
+  (const frsh_contract_t *new_contract,
+   const frsh_vres_id_t vres);
+
+
+/**
+ * frsh_contract_renegotiate_async()
+ *
+ * The operation enqueues a renegotiate operation for an existing
+ * vres, and returns immediately. The renegotiate operation is
+ * performed asynchronously, as soon as it is practical; meanwhile the
+ * system operation will continue normally. When the renegotiation is
+ * made, if the on-line admission test is enabled it determines
+ * whether the contract can be admitted or not based on the current
+ * contracts established in the system. If it cannot be admitted, the
+ * old contract remains in effect. If it can be admitted, it
+ * recalculates all necessary parameters for the contracts already
+ * present in the system.
+ *
+ * When the operation is completed, notification is made to the
+ * caller, if requested, via a signal. The status of the operation (in
+ * progress, admitted, rejected) can be checked with the
+ * frsh_vres_get_renegotiation_status() operation.  The argument
+ * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
+ * signal value and in this case signal_info is to be sent with the signal.
+ *
+ * @param[in] new_contract   New contract parameters for the new
+ *                           situation if approved.
+ * @param[in] vres           vres_id on which to do the renegotiation.
+ * @param[in] signal_to_notify  Signal number to use to notify vres of
+ *                           the negotiation result.  If
+ *                           FRSH_NULL_SIGNAL,  no signal will be raised.
+ * @param[in] signal_info:   Associated info that will come with the
+ *                           signal.  This parameter will be ignored
+ *                           if signal_to_notify == FRSH_NULL_SIGNAL.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if the new_contract argument is NULL, the
+ *     value of the vres argument is not in range or sig_notify is
+ *     neither NULL nor a valid POSIX signal \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *     running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ *     has been cancelled or it is not valid
+ *
+ **/
+int frsh_contract_renegotiate_async
+  (const frsh_contract_t *new_contract,
+   const frsh_vres_id_t vres,
+   const frsh_signal_t                     signal_to_notify,
+   const frsh_signal_info_t                signal_info);
+
+
+/**
+ * frsh_vres_get_renegotiation_status()
+ *
+ * The operation reports on the status of the last renegotiation
+ * operation enqueued for the specified vres. It is callable even
+ * after notification of the completion of such operation, if
+ * requested.
+ *
+ * If the vres is not and has not been involved in any of the
+ * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
+ * operations, the status returned is FRSH_RS_NOT_REQUESTED
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if the renegotiation_status argument is
+ *     NULL or the value of the vres argument is not in range \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *     running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ *     has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_renegotiation_status
+  (const frsh_vres_id_t vres,
+   frsh_renegotiation_status_t *renegotiation_status);
+
+/*@}*/
+
+////////////////////////////////////////////////////////////////////////
+//           CHANGE OF MODE: GROUPS OF CONTRACTS
+////////////////////////////////////////////////////////////////////////
+/**
+ * @defgroup groupofcontracts Group of contracts
+ * @ingroup core
+ *
+ * The following functions are used to negotiate atomically more than
+ * one contract.  This allows to build complex applications by
+ * splitting them in individual contracts that are negotiated
+ * simultaneously and atomically.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_group_change_mode_sync()
+ *
+ * This function performs a set of negotiation operations which can
+ * include: adding new contracts (neg), modifying existing vres (reneg)
+ * or cancelling existing vres (cancel).
+ *
+ * If one of the group operations has a NULL value, unless it causes an
+ * inconsistency the system will suppose that no operation of that
+ * type (neg, reneg or cancel) should be done.
+ *
+ * The virtual resources resulting from negotiations of new contracts are
+ * returned in the parameter 'new_vres' which must be provided by the user.
+ *
+ * If the on-line admission test is enabled, FRSH analizes the
+ * schedulability of the context that would  result in the new
+ * contract situation with removed, changed and added contracts.
+ *
+ * A successful return code will mean that all contracts have been
+ * accepted  and all required operations (creation, cancellation or
+ * update of vres) have been carried out to reach the new running
+ * context.
+ *
+ * If any of the contracts is not accepted a corresponding error shall be
+ * returned and no changes will be made to the previously running context.
+ *
+ * This call is a synchronous, potentially blocking operation.  It
+ * returns when the system has rejected the contracts or accepted
+ * and made them effective.
+ *
+ * @param[in] contracts_to_neg    List of new contracts to negotiate
+ * @param[in] contracts_to_reneg  List of contracts to renegotiate
+ * @param[in] vres_to_reneg       List of vres to renegotiate
+ * @param[in] vres_to_cancel      List of vres to cancel
+ * @param[out] new_vres           List of vres of new contracts.
+ *
+ * @return 0 if no error \n
+ *    FRSH_ERR_BAD_ARGUMENT Invalid pointer or group identifier. \n
+ *    FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS contract_label not unique. \n
+ *    FRSH_ERR_NOT_CONTRACTED_VRES: One of the provided vres_ids
+ *       is not recognised. \n
+ *    FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD The calling thread
+ *       is not scheduled under FRSH. \n
+ *    FRSH_ERR_INVALID_SCHEDULER_REPLY: The scheduler is wrong or
+ *       not running. \n
+ *    FRSH_ERR_INTERNAL_ERROR:  Erroneous binding or malfunction of
+ *       FRSH main scheduler. \n
+ *    FRSH_ERR_REJECTED_CONTRACT:  The negotiation of one of the
+ *       proposed contracts has failed.
+ **/
+int frsh_group_change_mode_sync
+                            (const frsh_contracts_group_t *contracts_to_neg,
+                             const frsh_contracts_group_t *contracts_to_reneg,
+                             const frsh_vres_group_t      *vres_to_reneg,
+                             const frsh_vres_group_t      *vres_to_cancel,
+                             frsh_vres_group_t            *new_vres);
+
+/**
+ * frsh_group_change_mode_async()
+ *
+ * This is an asynchronous (non-blocking) version of the previous function,
+ * frsh_group_change_mode_sync() and thus, it returns inmediately.
+ *
+ * The status of the change of mode and the identifiers for new virtual
+ * resources must be requested with the function 'frsh_group_get_status'
+ * by using the return parameter 'group'.
+ *
+ * As in the asynchronous renegotiations, when the operation is completed,
+ * the user is notified with a signal so he can check the final result with
+ * 'frsh_group_get_status'. In case that FRSH_NULL_SIGNAL is used, no
+ * signal will be sent to the user.
+ *
+ * @param[in] contracts_to_neg    List of new contracts to negotiate
+ * @param[in] contracts_to_reneg  List of contracts to renegotiate
+ * @param[in] vres_to_reneg       List of vres to renegotiate
+ * @param[in] vres_to_cancel      List of vres to cancel
+ * @param[in] signal              Signal number to notify completion of
+ *                                the change of mode. If FRSH_NULL_SIGNAL,
+ *                                no signal will be raised.
+ * @param[in] signal_info         Data associated to the signal
+ * @param[out] group              The group identifier to get the status
+ *
+ * @return 0 if no error \n
+ *    FRSH_ERR_BAD_ARGUMENT Invalid pointer, signal or group identifier. \n
+ *    FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS contract_label not unique. \n
+ *    FRSH_ERR_NOT_CONTRACTED_VRES: One of the provided vres_ids
+ *       is not recognised. \n
+ *    FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD The calling thread
+ *       is not scheduled under FRSH. \n
+ *    FRSH_ERR_INVALID_SCHEDULER_REPLY: The scheduler is wrong or
+ *       not running. \n
+ *    FRSH_ERR_INTERNAL_ERROR:  Erroneous binding or malfunction of
+ *       FRSH main scheduler.
+ **/
+int frsh_group_change_mode_async
+                            (const frsh_contracts_group_t *contracts_to_neg,
+                             const frsh_contracts_group_t *contracts_to_reneg,
+                             const frsh_vres_group_t      *vres_to_reneg,
+                             const frsh_vres_group_t      *vres_to_cancel,
+                             const frsh_signal_t          signal,
+                             const frsh_signal_info_t     signal_info,
+                             frsh_group_id_t              *group);
+
+/**
+ * frsh_group_get_status()
+ *
+ * This function is similar to 'frsh_vres_get_renegotiation_status' but it
+ * is intented for group negotiations (changes of mode).
+ *
+ * The operation reports on the status of the last negotiation
+ * operation enqueued for the specified group identifier.
+ *
+ * The status value can be one of the following values:
+ *
+ *    - FRSH_RS_IN_PROGRESS: the change of mode is in progress
+ *    - FRSH_RS_REJECTED: the change of mode was not accepted
+ *    - FRSH_RS_ADMITTED: the change of mode was accepted
+ *    - FRSH_RS_NOT_REQUESTED: no change of mode has been requested yet
+ *
+ * When status returns 'FRSH_RS_ADMITTED', the array 'new_vres' contains
+ * the values for the new virtual resources (if there was any).
+ *
+ * This function frees the group identifier when status returns something
+ * different than FRSH_RS_IN_PROGRESS so further calls to this function may
+ * return inconsistent values.
+ *
+ * @param[in]  group     The group identifier
+ * @param[out] status    The status of the change of mode
+ * @param[out] new_vres  List of vres for the negotiation of new contracts.
+ *
+ * @return 0 if no error \n
+ *    FRSH_ERR_BAD_ARGUMENT Invalid pointer, signal or group identifier. \n
+ *    FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS contract_label not unique. \n
+ *    FRSH_ERR_NOT_CONTRACTED_VRES: One of the provided vres_ids
+ *       is not recognised. \n
+ *    FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD The calling thread
+ *       is not scheduled under FRSH. \n
+ *    FRSH_ERR_INVALID_SCHEDULER_REPLY: The scheduler is wrong or
+ *       not running. \n
+ *    FRSH_ERR_INTERNAL_ERROR:  Erroneous binding or malfunction of
+ *       FRSH main scheduler.
+ **/
+int frsh_group_get_status(const frsh_group_id_t       group,
+                          frsh_renegotiation_status_t *status,
+                          frsh_vres_group_t           *new_vres);
+
+
+/*@}*/
+
+
+////////////////////////////////////////////////////
+//           OBTAINING INFORMATION FROM THE SCHEDULER
+////////////////////////////////////////////////////
+
+/**
+ * @defgroup getschedinfo Obtaining information from the scheduler
+ *
+ * @ingroup core
+ *
+ * The following functions are used to obtain available budget and
+ * resource usage in the system.  They can be used to adapt the
+ * execution of threads according to the load of the system.
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_config_is_admission_test_enabled()
+ *
+ * Returns true if the system is
+ * configured with the on-line admission test enabled, or false
+ * otherwise.  This situation can only be changed at compile time.
+ **/
+bool frsh_config_is_admission_test_enabled();
+
+/**
+ * frsh_vres_get_usage()
+ *
+ * This function stores the current execution time spent by the
+ * threads bound to the specified vres in the variable pointed to by
+ * cpu_time.
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
+ *     cpu_time is NULL \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *     running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRESR : if the vres of the calling thread
+ *     has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_usage
+   (const frsh_vres_id_t vres,
+    frsh_rel_time_t *spent);
+
+
+/**
+ * frsh_vres_get_job_usage()
+ *
+ * Get the execution time of the current job of the specified virtual
+ * resource for a bounded or synchronized workload.
+ **/
+int frsh_vres_get_job_usage
+    (const frsh_vres_id_t vres,
+     frsh_rel_time_t *spent);
+
+
+/**
+ * frsh_vres_get_remaining_budget()
+ *
+ * This function stores in the variable pointed to by budget the
+ * remaining execution-time budget associated with the specified
+ * vres.
+ *
+ *  @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
+ *     budget is NULL \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *     running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ *     has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_remaining_budget
+   (const frsh_vres_id_t vres,
+    frsh_rel_time_t *budget);
+
+
+/**
+ * frsh_vres_get_budget_and_period()
+ *
+ * This function stores in the variables
+ * pointed to by budget and period, the execution-time budget and the
+ * period respectively associated with the specified vres. If any of
+ * these pointers is NULL, the corresponding information is not stored.
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range,
+ *     or budget and period are both NULL \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *     running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ *     has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_budget_and_period
+   (const frsh_vres_id_t vres,
+    frsh_rel_time_t *budget,
+    frsh_rel_time_t *period);
+
+/*@}*/
+
+/////////////////////////////////////////////////////////////////////
+//           SERVICE THREAD TUNING
+/////////////////////////////////////////////////////////////////////
+/**
+ * @defgroup servthtuning Service thread tuning
+ *
+ * @ingroup core
+ *
+ * The following functions are used to obtain available budget and
+ * resource usage in the system.  They can be used to adapt the
+ * execution of threads to the load of the system.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_service_thread_set_data()
+ *
+ * This function allows the application to change the period and
+ * budget of the service thread that makes the
+ * negotiations. Increasing the utilization of this thread makes the
+ * negotiations faster, but introduces additional load in the system
+ * that may decrease the bandwidth available for the vres. For this
+ * call, the system will make a schedulability analysis to determine
+ * if the new situation is acceptable or not. This is reported back in
+ * the variable pointed to by accepted. If the new service thread data
+ * is accepted, the system will reassign budgets and periods to the
+ * vres according to the new bandwidth available, in the same way
+ * as it does for a regular contract negotiation.
+ *
+ * When its budget is exhausted, the service thread may run in the
+ * background
+ *
+ * The service thread starts with a default budget and period that are
+ * configurable
+ *
+ * Implementation dependency: in the fixed priority implementtaion of
+ * frsh, the default priority is lower than the priority of any vres,
+ * but higher than the background. According to the
+ * implementation-dependent module the priority is adjustable by means
+ * of a function that changes its preemption level
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT : if any of the pointer arguments is NULL or
+ *     the budget value is greater than the period value \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *     running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ *     has been cancelled or it is not valid
+ *
+ **/
+int frsh_service_thread_set_data (const frsh_rel_time_t *budget,
+                                  const frsh_rel_time_t *period,
+                                  bool                  *accepted);
+
+/**
+ * frsh_service_thread_get_data()
+ *
+ * this function returns in the variables pointed by budget and
+ * period, respectively, the current budget and period of the service
+ * thread.
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT : if any of the pointer arguments is NULL \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *     scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *     running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ *     has been cancelled or it is not valid
+ *
+ **/
+int frsh_service_thread_get_data
+   (frsh_rel_time_t *budget,
+    frsh_rel_time_t *period);
+
+
+/*@}*/
+
+
+////////////////////////////////////////////////////////////////////////
+//           BACKGROUND MANAGEMENT
+////////////////////////////////////////////////////////////////////////
+
+//A round-robin background scheduling policy is available for those
+//threads that do not have real-time requirements. Because some of
+//these threads may require sharing information with other threads run
+//by regular vres.  Special background contracts may be created for
+//specifying the synchronization requirements.
+
+//The way of specifying a background contract is by setting
+//contract_type to FRSH_CT_BACKGROUND. Negotiation may fail if the contract uses
+//shared_objects. If the contract has no shared_objects the returned
+//vres id represents the background and may be used to bind more
+//than one thread. If the contract has shared objects a vres is
+//created to keep track of them, but the associated threads are
+//executed in the background, together with the other background
+//threads
+
+
+////////////////////////////////////////////////////////////////////////
+//           OTHER
+////////////////////////////////////////////////////////////////////////
+
+/**
+ * Returns resource id of local CPU.
+ *
+ * The ID is determined from environment variable FRSH_CPU_ID or, if
+ * that is not defined, the compile time default (defined in
+ * config.target/omk).
+ */
+frsh_resource_id_t frsh_get_local_cpu_id(void);
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_CORE_H_
diff --git a/src/frsh-include/frsh_core_types.h b/src/frsh-include/frsh_core_types.h
new file mode 100644 (file)
index 0000000..d355c25
--- /dev/null
@@ -0,0 +1,222 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_core_types.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+
+#ifndef   FRSH_CORE_TYPES_H_
+#define   FRSH_CORE_TYPES_H_
+
+#include <stdbool.h>
+#include "frsh_time_types.h"
+#include "frsh_configuration_parameters.h"
+#include "frsh_opaque_types.h"
+#include "frsh_shared_objects_types.h"
+#include "frsh_spare_capacity_types.h"
+
+#include "frsh_implementation_specific_types.h"
+#include "frsh_hierarchical_types.h"
+#include "frsh_distributed_types.h"
+#include "frsh_error.h"
+
+#include "fosa.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_core_types.h
+ **/
+
+
+/**
+ * \addtogroup core
+ **/
+/*@{*/
+
+
+/** identifier of a frsh thread **/
+typedef fosa_thread_id_t frsh_thread_id_t;
+
+
+/** thread attributes object **/
+typedef fosa_thread_attr_t frsh_thread_attr_t;
+
+/**
+ *  The type references a function that may become a thread's
+ *  code
+ **/
+typedef fosa_thread_code_t frsh_thread_code_t;
+
+
+/** signal number; it is an integer type **/
+typedef fosa_signal_t frsh_signal_t;
+
+#define FRSH_NULL_SIGNAL      FOSA_NULL_SIGNAL
+
+
+#define FRSH_SIGNAL_MIN       FOSA_SIGNAL_MIN
+#define FRSH_SIGNAL_MAX       FOSA_SIGNAL_MAX
+
+
+typedef fosa_signal_info_t frsh_signal_info_t;
+
+
+/** Kind of workload expected in vres: bounded or indeterminate **/
+typedef enum {
+    FRSH_WT_BOUNDED       = 0,
+    FRSH_WT_INDETERMINATE = 1,
+    FRSH_WT_SYNCHRONIZED  = 2
+} frsh_workload_t;
+/**
+ * In the synchronized workload the virtual resource hosts one or more
+ * threads that synchronize the execution of their jobs with the start
+ * of the virtual resource's period. In this kind of workload, once
+ * the threads that were activated at the beginning of the period
+ * finish their current job, the virtual resource may return any
+ * unused capacity to the system. This kind of workload can be
+ * scheduled using a regular periodic server that has the properties
+ * of being simple, having less overhead, and being able to increase
+ * the schedulability of periodic synchronized threads
+ **/
+
+#define FRSH_NULL_DEADLINE     (frsh_rel_time_t *)NULL
+// #define FRSH_NULL_SIGNAL       0 /* Defined at frsh_adaption.h */
+
+/** Negotiation status: In_progress, rejected, admitted, not_requested **/
+typedef enum {FRSH_RS_IN_PROGRESS,
+              FRSH_RS_REJECTED,
+              FRSH_RS_ADMITTED,
+              FRSH_RS_NOT_REQUESTED} frsh_renegotiation_status_t;
+
+/**
+ *  Vres Id type, that identifies a vres created to manage a given
+ *  contract
+ **/
+typedef FRSH_VRES_ID_T_OPAQUE frsh_vres_id_t;             // => 0
+
+/** Contract ressource type:  processor, network, memory **/
+typedef enum {
+    FRSH_RT_PROCESSOR = 0,
+    FRSH_RT_NETWORK   = 1,
+    FRSH_RT_MEMORY    = 2,
+    FRSH_RT_DISK      = 3,
+    FRSH_RT_FPGA      = 4,
+    FRSH_RT_LCD       = 5
+} frsh_resource_type_t;
+
+/** Ressource Id: processor_id or network_id **/
+/**********************************************/
+typedef fosa_resource_id_t frsh_resource_id_t;
+
+/** Kind of contract: regular, background or dummy **/
+typedef enum {
+        FRSH_CT_REGULAR    = 0,
+        FRSH_CT_BACKGROUND = 1,
+        FRSH_CT_DUMMY      = 2
+} frsh_contract_type_t;
+
+// The name of this constant has been updated to have the FRSH_ prefix
+typedef char frsh_contract_label_t[FRSH_CONTRACT_LABEL_MAXLENGTH + 1];
+
+/**
+ *  Contract parameters type; it is an opaque type (i.e. the internal
+ *  structure of this data type is implementation dependent). The user
+ *  can access and modify the parameters of a contract only with the
+ *  proper functions, and should never access the data directly.
+ **/
+typedef FRSH_CONTRACT_T_OPAQUE  frsh_contract_t;
+
+
+/** List of vres **/
+typedef  struct {
+  int             size;
+  frsh_vres_id_t  vres[FRSH_MAX_GROUP_OPS];
+} frsh_vres_group_t;
+
+/** List of contracts to negotiate **/
+typedef struct {
+    int  size;
+    frsh_contract_t contracts[FRSH_MAX_GROUP_OPS];
+} frsh_contracts_group_t;
+
+typedef FRSH_GROUP_ID_T_OPAQUE frsh_group_id_t;
+
+/**
+ * An abstract synchronization object is defined by the application.
+ * This object can be used by an application to wait for an event to
+ * arrive by invoking the frsh_sychobj_wait() operation.  It
+ * can also be used to signal the event either causing a waiting
+ * vres to wake up, or the event to be queued if no vres is
+ * waiting for it.
+ **/
+typedef FRSH_SYNCHOBJ_HANDLE_T_OPAQUE frsh_synchobj_handle_t;
+
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif   /* !FRSH_CORE_TYPES_H_ */
diff --git a/src/frsh-include/frsh_cpp_macros.h b/src/frsh-include/frsh_cpp_macros.h
new file mode 100644 (file)
index 0000000..e3b8462
--- /dev/null
@@ -0,0 +1,72 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+#ifndef _FRSH_CPP_MACROS_H_
+#define _FRSH_CPP_MACROS_H_
+
+#if defined(__cplusplus)
+#define FRSH_CPP_BEGIN_DECLS  extern "C" {
+#else
+#define FRSH_CPP_BEGIN_DECLS
+#endif
+
+#if defined(__cplusplus)
+#define FRSH_CPP_END_DECLS }
+#else
+#define FRSH_CPP_END_DECLS
+#endif
+
+#endif // _FRSH_CPP_MACROS_H_
+
diff --git a/src/frsh-include/frsh_debug_and_trace.h b/src/frsh-include/frsh_debug_and_trace.h
new file mode 100644 (file)
index 0000000..54af6aa
--- /dev/null
@@ -0,0 +1,165 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+//
+// 23-Jul-2007 SANGORRIN: create this file for debugging functions
+// 31-Jul-2007 TELLERIA:  Change "debug" for "trace"
+// -----------------------------------------------------------------------
+#ifndef FRSH_DEBUG_H
+#define FRSH_DEBUG_H
+
+#include <stdio.h> // for vprintf
+#include <stdbool.h> // for bool
+#include <stdarg.h> // for va_list, va_start and va_end
+#include "fosa.h"
+#include "frsh_debug_and_trace_types.h"
+#include "fosa_configuration_parameters.h" /* FOSA_CLOCK_REALTIME */
+#include "fosa_clocks_and_timers.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+// Tune the following FLAGS to select the debugging messages to be generated
+#define FRSH_TRACE_CALLBACKS false
+#define FRSH_TRACE_SERVICE_TH false
+#define FRSH_TRACE_WATCHDOG false
+#define FRSH_TRACE_SPORADIC_SERVER false
+#define FRSH_TRACE_REPLENISHMENTS false
+#define FRSH_TRACE_ROUND_ROBIN false
+#define FRSH_TRACE_BOUNDED_JOB false
+#define FRSH_TRACE_SYNCHRONIZE_WORKLOAD false
+#define FRSH_TRACE_ADMISSION_TEST false
+#define FRSH_TRACE_ADMISSION_RESULT false
+
+#define FRSH_TRACE_THREAD_INDEX false
+#define FRSH_TRACE_VRES_INDEX false
+
+#define FRSH_TRACE_DISTRIBUTED false
+
+#define QUICK_AND_DIRTY_FIX_JLDEMO true
+
+
+/**
+ * frsh_trace_point_insert()
+ *
+ * Insert an application-defined trace-point identifier together with
+ * a timestamp into the trace log, if tracing is enabled; the
+ * identifier is an integer that must be between two configurable
+ * values defined in the FRSH API as constants; if tracing is not
+ * enabled, this function has no effect.
+ */
+int frsh_trace_point_insert(frsh_trace_point_id_t ipoint);
+
+/** If FRSH_TRACE_TS_MSECS is defined, each trace line is prefixed
+    with a msec counter **/
+#define FRSH_TRACE_TS_MSECS
+
+/* These variables live defined in frsh_error.c */
+/************************************************/
+extern fosa_abs_time_t frsh_trace_init_timespec;
+extern long frsh_trace_init_timemsec;
+
+extern int global_error_condition;  /* Used to propagate error
+                                     * conditions in debugging */
+
+static inline long int FRSH_GET_TIMESTAMP_MSECS()
+{
+    int terror = -1;
+    fosa_abs_time_t current_time;
+    long int current_time_msec = -1;
+    long int result = -1;
+
+    PRW(  fosa_clock_get_time(FOSA_CLOCK_REALTIME, &current_time)  );
+    current_time_msec = fosa_abs_time_to_msec(current_time);
+
+    result = current_time_msec - frsh_trace_init_timemsec;
+
+    return result;
+}
+
+static inline long int FRSH_TIMESTAMP_TO_RELATIVE_MSECS(const fosa_abs_time_t *timestamp)
+{
+    long int time_msecs = -1;
+
+    time_msecs = fosa_abs_time_to_msec(*timestamp);
+
+    return time_msecs - frsh_trace_init_timemsec;
+}
+
+/**
+ * FRSH_TRACE()
+ *
+ * If the boolean value is true, print the format line optionally
+ * preceded by a timestamp in ms relative to the start of the
+ * program.
+ *
+ * Due to the "..." argument passing, this function cannot be
+ * inlined.
+ **/
+void FRSH_TRACE(bool is_active, const char *format, ...);
+
+FRSH_CPP_END_DECLS
+
+#endif
diff --git a/src/frsh-include/frsh_debug_and_trace_types.h b/src/frsh-include/frsh_debug_and_trace_types.h
new file mode 100644 (file)
index 0000000..a0e54e5
--- /dev/null
@@ -0,0 +1,85 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+//
+// 23-Jul-2007 SANGORRIN: create this file for debugging functions
+// 31-Jul-2007 TELLERIA:  Change "debug" for "trace"
+// -----------------------------------------------------------------------
+#ifndef   FRSH_DEBUG_AND_TRACE_TYPES_H_
+#define   FRSH_DEBUG_AND_TRACE_TYPES_H_
+
+FRSH_CPP_BEGIN_DECLS
+
+/**  identifier of a trace point **/
+typedef int frsh_trace_point_id_t;
+
+/** constants that describe the valid range of trace point identifiers **/
+#define FRSH_TRACE_POINT_ID_MIN 0
+#define FRSH_TRACE_POINT_ID_MAX 10
+
+FRSH_CPP_END_DECLS
+
+#endif /* !FRSH_DEBUG_AND_TRACE_TYPES_H_ */
diff --git a/src/frsh-include/frsh_distributed.h b/src/frsh-include/frsh_distributed.h
new file mode 100644 (file)
index 0000000..ef602d8
--- /dev/null
@@ -0,0 +1,730 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_distributed.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_DISTRIBUTED_H_
+#define _FRSH_DISTRIBUTED_H_
+
+
+/**
+ * @file frsh_distributed.h
+ **/
+
+
+#include "frsh_distributed_types.h"
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+// this global variable is assigned by frsh_distributed_init()
+extern frsh_resource_id_t THE_FRSH_CPU_ID;
+
+typedef enum {
+        FRSH_NETPF_FRESCAN      = 0,
+        FRSH_NETPF_RTEP         = 1,
+        FRSH_NETPF_UNIX         = 2,
+        FRSH_NETPF_FWP          = 3,
+        FRSH_NETPF_CLUSTER_TREE = 4,
+        FRSH_NETPF_ITEM         = 5,
+} frsh_netpf_t;
+
+/**
+ * @defgroup distributed Distributed module
+ *
+ * This module defines the functions and typedefs for use in
+ * distributed applications.
+ *
+ * Each network is identified by its resource_id and FRSH hides its
+ * characteristics completely.  The type of network is implied with
+ * its ID via a configuration table defined at compile time.
+ *
+ * FRSH uses the "message" as the atomic unit for every exchange.
+ * Queue sizes are measured in number of pending messages.
+ *
+ * FRSH provides a function to calculate the transmision time needed
+ * for a certain message size in a network as well as the maximum
+ * message size that can admit.
+ *
+ * Note also that package delivery guarantee is protocol dependent.
+ * For protocols in which the order is no guaranteed, the application
+ * needs to add extra info to detect possible package disorder.
+ *
+ * Summary of typical steps.
+ *
+ * 1.  Map (internally in FRSH implementation)
+ *     -   node--> network_addresses
+ *     -   network --> resource_id's
+ *     -   unidirectional communication channel --> stream_id
+ *     -   other config --> protocol_info.
+ *
+ * 2.  In a sending node:
+ *     2.1. Negotiates a "network contract" per communication channel
+ *          that is used in the application.  In the contract it is
+ *          specified:
+ *          -  frsh_resource_type = FRSH_RT_NETWORK.
+ *          -  frsh_resource_id = <network id #>
+ *          -  budget:  Time needed to send the required data per period.
+ *                 (you can use frsh_netinfo_*() functions for this).
+ *          -  period:  Period of sendings.
+ *          -  Queueing info:  How will sends be queued at sendEndpoint.
+ *          -  Other protocol dependent function in protocol_contract_info.
+ *     2.2. Create a send_endpoint per any unidirectional stream that will
+ *          be used in sending
+ *          resource_id --> the network through which the stream will
+ *                       flow (this is extra info needed for coherency
+ *                       with the bind).
+ *          destinator --> network_address of the destination.
+ *          stream_id --> the unidirectional communication channel.
+ *     2.3. Bind the send_endpoint to the network contract negotiated
+ *          above.
+ *     2.4. The (processor) sending vres invokes frsh_send_(a)sync() to
+ *          send the data through the corresponding stream.
+ *
+ * 3.  In a receiving node:
+ *     3.1. Create a receive_endpoint per any unidirectional stream
+ *          that will be used in receiving.
+ *     3.2. The processor expecting a reception of message invokes
+ *          frsh_receive_(a)sync() to read the incoming data.
+ *
+ * 4.  When all comunication is finished and the channel is no longer
+ *     needed the nodes will destroy the send and receive endpoints
+ *     and the network contract will be canceled.
+ **/
+
+/**
+ * frsh_distributed_init(void)
+ *
+ * This operation initializes all the installed networks and the structures
+ * that are necessary for the distributed module. Currently it is called by
+ * frsh_init so it is not necessary that the user calls it again.
+ *
+ *   0: No error \n
+ *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ *
+ **/
+int frsh_distributed_init(void);
+
+//////////////////////////////////////////////////////////////////////
+//           CONTRACT ASPECTS
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup distcontract Contract Info for Distributed Systems
+ * @ingroup distributed
+ *
+ * These functions help you calculate the needed budget for network
+ * contracts and also to include protocol dependent info in contract
+ * parameters.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_network_get_max_message_size()
+ *
+ * This operation gives the maximum number of bytes that can be sent
+ * at a time through the send function when using the network designated by
+ * 'resource_id' and sending it to 'destination'.
+ *
+ * If the application needs to send bigger messages it will have to
+ * split them.
+ *
+ * Some protocols, like IP, are capable of sending large messages
+ * (and use fragmentation internally) but other protocols don't.
+ *
+ * @param[in] resource_id The network we want the tx time from.
+ * @param[in] destination The destination address
+ * @param[out] max_size The maximum number of bytes for each message
+ *
+ * @return
+ *   FRSH_NO_ERROR \n
+ *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ *   a network accessible from the current processing node \n
+ *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
+ *   invalid \n
+ *
+ **/
+int frsh_network_get_max_message_size
+   (const frsh_resource_id_t resource_id,
+    const frsh_network_address_t destination,
+    size_t *max_size);
+
+/**
+ * frsh_network_bytes_to_budget()
+ *
+ * This operation converts a number of bytes into a temporal budget for
+ * a specific network. Network overheads are not included here but are
+ * considered internally when negotiating a specific contract.
+ *
+ * @param[in] resource_id The network
+ * @param[in] nbytes Number of bytes
+ * @param[out] budget The network budget for nbytes
+ *
+ * @return
+ *   FRSH_NO_ERROR \n
+ *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ *   a network accessible from the current processing node \n
+ *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
+ *   than zero \n
+ *
+ **/
+int frsh_network_bytes_to_budget
+   (const frsh_resource_id_t resource_id,
+    const size_t nbytes,
+    frsh_rel_time_t *budget);
+
+/**
+ * frsh_network_budget_to_bytes()
+ *
+ * This operation converts a temporal budget into a number of bytes for
+ * a specific network. Network overheads are not included.
+ *
+ * @param[in] resource_id The network
+ * @param[in] budget The network budget for nbytes
+ * @param[out] nbytes Number of bytes
+ *
+ * @return
+ *   FRSH_NO_ERROR \n
+ *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ *   a network accessible from the current processing node \n
+ *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
+ *   an invalid time value \n
+ *
+ **/
+int frsh_network_budget_to_bytes
+   (const frsh_resource_id_t resource_id,
+    const frsh_rel_time_t *budget,
+    size_t *nbytes);
+
+/**
+ * frsh_network_get_min_effective_budget()
+ *
+ * This operation gets the minimum effective budget for a network. Each message
+ * consumes a contracted budget in "chunks" (i.e: packets) that we call
+ * minimum effective budget.
+ *
+ * A negotiated contract, for N bytes in a period T, means that there is a
+ * virtual resource that reserves for the user:
+ *
+ *   Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
+ *
+ * Note that if the user decides not to send these N bytes at once but, say,
+ * one byte at a time, it will consume one "CHUNK" at a time and the reserved
+ * budget will become exhausted before sending all the bytes.
+ *
+ * @param[in] resource_id The network
+ * @param[out] budget The network budget
+ *
+ * @return
+ *   FRSH_NO_ERROR \n
+ *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ *   a network accessible from the current processing node \n
+ *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_network_get_min_effective_budget
+   (const frsh_resource_id_t resource_id,
+    frsh_rel_time_t *budget);
+
+/**
+ * frsh_contract_set_queueing_info()
+ *
+ * This function adds queueing parameters that will be used in the
+ * sendEndpoint when the sendEndpoint is bound to the vres.
+ **/
+int frsh_contract_set_queueing_info(frsh_endpoint_queueing_info_t queueing_info,
+                                    frsh_contract_t *contract);
+
+/**
+ * frsh_contract_get_queueing_info()
+ *
+ * This function gets the queueing parameters that were specified in
+ * the network contract.
+ **/
+int frsh_contract_get_queueing_info(const frsh_contract_t *contract,
+                                    frsh_endpoint_queueing_info_t *queueing_info);
+
+/**
+ * frsh_contract_set_protocol_info
+ *
+ * We add protocol info to the contract
+ **/
+int frsh_contract_set_protocol_info(frsh_protocol_info_t protocol_info,
+                                    frsh_contract_t *contract);
+
+/**
+ * frsh_contract_get_protocol_info
+ *
+ * We get protocol info from the contract
+ **/
+int frsh_contract_get_protocol_info(frsh_contract_t *contract,
+                                    frsh_protocol_info_t *protocol_info);
+
+/**
+ * frsh_contract_marshal
+ *
+ * Convert a contract to a sequence of bytes of minimum size so it can
+ * be sent through the network with the minimum amount of bytes.
+ *
+ **/
+
+int frsh_contract_marshal(const frsh_contract_t *contract,
+                          unsigned char         *buffer,
+                          const size_t          buffer_size,
+                          size_t                *size);
+
+/**
+ * frsh_contract_unmarshal
+ *
+ * Convert a sequence of bytes generated by frsh_contract_marshal to a contract
+ *
+ **/
+
+int frsh_contract_unmarshal(frsh_contract_t      *contract,
+                            const unsigned char  *marshal_bytes,
+                            const size_t         size);
+
+/*@}*/
+//////////////////////////////////////////////////////////////////////
+//           TWO STEP NEGOTIATION
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup twostepnego Two Step Negotiation
+ * @ingroup distributed
+ *
+ * Using the core services of FRSH, contracts may be negotiated in a
+ * single step.
+ *
+ * An alternative two-step negotiation process is introduced in the
+ * distribution module: the first step involves the reservation of the
+ * resources, but without the right to use them, and the second step
+ * is the commitment to use those resources.
+ *
+ * The rationale behind this approach is that in distributed systems,
+ * when a distributed transaction is being negotiated the system
+ * should only commit the virtual resources that were negotiated with
+ * various nodes in the system if the results of all negotiations
+ * match together. This approach enhances the efficiency since the
+ * actual temporal values of the virtual resources on distributed
+ * nodes are only changed if the initiator of the distributed
+ * transaction is satisfied with the results of the negotiations.
+ *
+ * After the reservation, it is not necessary to change the actual
+ * virtual resource attributes (and modifying the schedule) on each
+ * node before the initiator of the distributed transaction knows the
+ * amount of available virtual resources. A renegotiation of a
+ * reserved virtual resource is possible, to harmonize for the
+ * available virtual resources in other parts of the system, before a
+ * final commitment is made.
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_contract_negotiate_reservation()
+ *
+ * Negotiate a service contract, obtaining a virtual resource id that
+ * represents a reservation of resources, but without the right to use
+ * those resources until the reservation is committed via
+ * frsh_vres_commit_reservation. In particular, this virtual resource
+ * cannot be bound until committed, but renegotiations are allowed for
+ * it.
+ */
+int frsh_contract_negotiate_reservation
+  (const frsh_contract_t *contract,
+   frsh_vres_id_t        *vres);
+
+/**
+ * frsh_vres_commit_reservation()
+ *
+ * Commit the resources reserved for a virtual resource through a
+ * frsh_contract_negotiate_reservation operation. The effects of
+ * subsequent calls to frsh_contract_negotiate_reservation and
+ * frsh_vres_commit_reservation are equivalent to a single call to
+ * frsh_contract_negotiate.
+ */
+int frsh_vres_commit_reservation
+   (const frsh_vres_id_t   vres);
+
+/* @} */
+
+
+
+//////////////////////////////////////////////////////////////////////
+//           TRANSMISSION SERVICES
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup txservices Transmission services
+ * @ingroup distributed
+ *
+ * These functions allow to create and manage endpoints for sending
+ * and receiving and to perform send and receive operations both
+ * synchronously (blocking) and asynchronously (non-blocking).
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_send_endpoint_create()
+ *
+ * This operation creates a unidirectional stream input endpoint
+ * through which, after the corresponding binding, it is possible to
+ * send data to a unicast or multicast destination.
+ *
+ * @param[in] resource_id  Identifier of the network referred in the
+ *                        network contract as a resource_id.
+ * @param[in] destination    FRSH abstraction of the protocol address for the
+ *                        destinator node.
+ * @param[in] stream_id   Identifier of the communication channel between
+ *                        the nodes.  Multiplexing is achieved by using
+ *                        different streams between the same nodes and the
+ *                        same network.
+ * @param[in] queueing_info Queueing params of the endpoint (size and
+ *                           policy).
+ * @param[in] protocol_info Optional protocol-dependent info.
+ * @param[out] endpoint   Placeholder for the endpoint object.
+ **/
+int frsh_send_endpoint_create
+        (frsh_resource_id_t     resource_id,
+         frsh_network_address_t    destination,
+         frsh_stream_id_t       stream_id,
+         frsh_send_endpoint_protocol_info_t protocol_info,
+         frsh_send_endpoint_t  *endpoint);
+
+/**
+ * frsh_send_endpoint_get_params()
+ *
+ * This operation returns in the variables associated to the
+ * endpoint at creation time.
+ **/
+int frsh_send_endpoint_get_params
+    (const frsh_send_endpoint_t  endpoint,
+     frsh_resource_id_t        *resource_id,
+     frsh_network_address_t       *destination,
+     frsh_stream_id_t          *stream,
+     frsh_send_endpoint_protocol_info_t  *protocol_info);
+
+/**
+ * frsh_send_endpoint_destroy()
+ *
+ * This operation eliminates any resources reserved for the referenced
+ * endpoint.  Pending messages will be discarded and processor-vres
+ * waiting in a synchronous operation will be awoken with an error
+ * code.
+ **/
+int frsh_send_endpoint_destroy
+     (frsh_send_endpoint_t  endpoint);
+
+/**
+ * frsh_send_endpoint_bind()
+ *
+ * This operation associates a send endpoint with a network vres,
+ * which means that messages sent through this endpoint will consume
+ * the vres's reserved bandwidth and its packets will be sent
+ * according to the contract established for that vres.
+ *
+ * If the endpoint is already bound to another vres, it is effectively
+ * unbound from it and bound to the specified one.  However if a vres
+ * is already bound to another endpoint an error is returned.
+ *
+ * A consistency check is done in which the resource_id specified at
+ * endpoint creation must correspond to the resource_id of the vres
+ * contract.
+ *
+ * @return  0 if successful \n
+ *      FRSH_ERR_BAD_ARGUMENT if the endpoint or the vres are not
+ *                            valid \n
+ *      FRSH_ERR_ALREADY_BOUND if the vres is already bound to some
+ *                               other send endpoint \n
+ *      FRSH_ERR_WRONG_NETWORK if the vres network id is not the same
+ *                               as the one in the endpoint \n
+ **/
+int frsh_send_endpoint_bind
+  (frsh_vres_id_t      vres,
+   frsh_send_endpoint_t  endpoint);
+
+/**
+ * frsh_send_endpoint_unbind()
+ *
+ * This operation unbinds a send endpoint from a vres. Endpoints with
+ * no vres associated cannot be used to send data, and they stay in
+ * that state  until they are either eliminated or bound again.
+ *
+ * @return 0 if successful \n
+ *         FRSH_ERR_NOT_BOUND if the endpoint was not bound \n
+ **/
+int frsh_send_endpoint_unbind
+  (frsh_send_endpoint_t  endpoint);
+
+/**
+ * frsh_send_endpoint_get_vres_id()
+ *
+ * This operation copies the id of the vres that is bound to the
+ * specified send endpoint into the variable pointed to by vres.
+ *
+ * @return 0 if successful \n
+ *         FRSH_ERR_NOT_BOUND if the endpoint was not bound \n
+ *         FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid or vres
+ *                               is NULL \n
+ **/
+int frsh_send_endpoint_get_vres_id
+  (const frsh_send_endpoint_t  endpoint,
+   frsh_vres_id_t            *vres);
+
+/**
+ * frsh_send_async()
+ *
+ * This operation sends a message stored in msg and of length size
+ * through the given endpoint. The operation is non-blocking and
+ * returns immediately.
+ *
+ * An internal frsh service will schedule the sending of messages and
+ * implement the communications sporadic vres  corresponding to the
+ * network vres bound to the given endpoint.
+ *
+ * @returns 0 if successful \n
+ *       FRSH_ERR_BAD_ARGUMENT if endpoint is not valid \n
+ *       FRSH_ERR_NOT_BOUND if endpoint is not bound to a valid vres \n
+ *       FRSH_ERR_TOO_LARGE if the message is too large for the
+ *                             network protocol \n
+ *       FRSH_ERR_BUFFER_FULL if the message has been discarded
+ *                            because the queue is full (and does not
+ *                            have the policy FRSH_QP_OLDEST \n
+ **/
+int frsh_send_async
+  (const frsh_send_endpoint_t  endpoint,
+   const void                  *msg,
+   const size_t                size);
+
+/**
+ * frsh_send_sync()
+ *
+ * Similar to previous function but now the sending vres gets blocked
+ * until the message is processed.
+ **/
+int frsh_send_sync
+  (const frsh_send_endpoint_t endpoint,
+   const void                 *msg,
+   size_t                      size);
+
+/**
+ * frsh_send_endpoint_get_status()
+ *
+ * This function tells the number of messages still pending in the
+ * endpoint queue, whether the network is up or down with some
+ * optional information which is protocol_dependent.
+ **/
+int frsh_send_endpoint_get_status
+        (const frsh_send_endpoint_t endpoint,
+         int *number_pending_msg,
+         frsh_endpoint_network_status_t *network_status,
+         frsh_protocol_status_t *protocol_status);
+
+/**
+ * frsh_receive_endpoint_create()
+ *
+ * This operation creates a receive endpoint associated with a
+ * undirectional stream within a network interface of the node.
+ *
+ * Receiving endpoints are not bound to any network vres, this is
+ * because don't originate any traffic.
+ *
+ * Note that the protocol address is not needed for reception because
+ * it can be determined internally by FRSH based on the resource_id.
+ *
+ * Note also that messages may come from diferent originators.
+ *
+ * @param[in] resource_id  Id of the network from which we listen.
+ * @param[in] stream_id  Id of the stream within the network.
+ * @param[in] queueing_info Buffering information(queue size and
+ *                          policy).
+ * @param[in] protocol_info Extra protocol info opaque for the
+ *                          application.
+ * @param[in] endpoin  Placeholder for the endpoint object.
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT if the stream or the network id are not
+ *      valid \n
+ **/
+int frsh_receive_endpoint_create
+  (frsh_resource_id_t        resource_id,
+   frsh_stream_id_t          stream_id,
+   frsh_endpoint_queueing_info_t queueing_info,
+   frsh_receive_endpoint_protocol_info_t protocol_info,
+   frsh_receive_endpoint_t  *endpoint);
+
+/**
+ * frsh_receive_endpoint_get_params()
+ *
+ * This operation returns in the variables associated to the
+ * endpoint at creation time.
+ **/
+int frsh_receive_endpoint_get_params
+     (const frsh_receive_endpoint_t  endpoint,
+     frsh_resource_id_t        *resource_id,
+     frsh_stream_id_t          *stream,
+     frsh_endpoint_queueing_info_t   *queueing_info,
+     frsh_receive_endpoint_protocol_info_t   *protocol_info);
+
+/**
+ * frsh_receive_endpoint_destroy()
+ *
+ * This operation eliminates any resources reserved for the referenced
+ * endpoint.  Pending messages will be discarded and processor-vres
+ * waiting in a synchronous operation will be awoken with an error
+ * code.
+ **/
+int frsh_receive_endpoint_destroy
+     (frsh_receive_endpoint_t  endpoint);
+
+
+/**
+ * frsh_receive_sync()
+ *
+ * If there are no messages available in the specified receive endpoint
+ * this operation blocks the calling thread waiting for a message to be
+ * received.
+ *
+ * When a message is available, if its size is less than or
+ * equal to the buffer_size, the function stores it in the variable
+ * pointed to by buffer and puts the number of bytes received in the
+ * variable pointed to by message size.
+ *
+ * The function fails with FRSH_ERR_NO_SPACE if the buffersize is
+ * too small for the message received.  In this case the message is
+ * lost.
+ *
+ * Messages arriving at a destination buffer that is full will be
+ * silently discarded (details in the queueing policy of the
+ * endpoint). The application is responsible of reading the receive
+ * endpoints with appropriate regularity, or of using a sequence
+ * number or some other mechanism to detect any lost messages.
+ *
+ * @return 0 if successful \n
+ *     FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
+ *       buffer or message_size are NULL.\n
+ *     FRSH_ERR_NO_SPACE if the message size is bigger than the
+ *       provided buffer \n
+ **/
+int frsh_receive_sync
+  (const frsh_receive_endpoint_t  endpoint,
+   void                           *buffer,
+   size_t                         buffer_size,
+   size_t                         *message_size,
+   frsh_network_address_t         *from);
+
+/**
+ * frsh_receive_async()
+ *
+ * This operation is similar to the previous one but it works in a non
+ * blocking (asynchronous) fashion.  If no message is available it
+ * returns with error FRSH_NO_MESSAGE.
+ *
+ * @return 0 if successful \n
+ *     FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
+ *       buffer or message_size are NULL \n
+ *     FRSH_NO_MESSAGE if no messages are available in the queue \n
+ *     FRSH_ERR_NO_SPACE if the message size is bigger than the
+ *       provided buffer \n
+ **/
+int frsh_receive_async
+  (const frsh_receive_endpoint_t  endpoint,
+   void                           *buffer,
+   size_t                         buffer_size,
+   size_t                         *message_size,
+   frsh_network_address_t         *from);
+
+
+/**
+ * frsh_receive_endpoint_get_status
+ *
+ * This function tells the number of messages still pending in the
+ * endpoint queue, whether the network is up or down and some optional
+ * information which is protocol dependent.
+ **/
+int frsh_receive_endpoint_get_status
+        (const frsh_receive_endpoint_t endpoint,
+         int *number_pending_messages,
+         frsh_endpoint_network_status_t *network_status,
+         frsh_protocol_status_t *protocol_status);
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_DISTRIBUTED_H_
diff --git a/src/frsh-include/frsh_distributed_types.h b/src/frsh-include/frsh_distributed_types.h
new file mode 100644 (file)
index 0000000..3053d15
--- /dev/null
@@ -0,0 +1,175 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef   FRSH_DISTRIBUTED_TYPES_H_
+#define   FRSH_DISTRIBUTED_TYPES_H_
+
+/**
+ * @file frsh_distributed_types.h
+ **/
+
+#include "frsh_opaque_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @addtogroup distributed
+ *
+ * @{
+ **/
+
+//opaque types for frsh endpoints
+typedef FRSH_SEND_ENDPOINT_T_OPAQUE frsh_send_endpoint_t;
+typedef FRSH_RECEIVE_ENDPOINT_T_OPAQUE frsh_receive_endpoint_t;
+
+/**
+ * The network_address type specifies the node or multicast address in
+ * a communication-protocol-independent way. The actual address is
+ * obtained via a configuration dependent mapping function
+ **/
+typedef unsigned int frsh_network_address_t;
+
+/**
+ * The port type specifies the information that is
+ * necessary to get in contact with the thread in the
+ * receiving node, in a protocol-independent way.
+ * The actual port number is obtained via a configuration
+ * dependent mapping function
+ **/
+typedef unsigned int frsh_stream_id_t;
+
+/**
+ * Extra information protocol dependent opaque for the application.
+ * It can be used in different places: contract negotiation, extra
+ * endpoint info, extra status info...
+ **/
+typedef struct {
+    void *body;
+    int size;
+} frsh_protocol_info_t;
+
+/**
+ * Protocol dependent information about the status of an endpoint
+ **/
+typedef struct {
+   void *body;
+   int size;
+} frsh_protocol_status_t;
+
+/**
+ * Protocol dependent information about extra parameters for
+ * send_endpoint definition.
+ **/
+typedef struct {
+   void *body;
+   int size;
+} frsh_send_endpoint_protocol_info_t;
+
+/**
+ * Protocol dependent information about extra parameters for
+ * receive_endpoint definition.
+ **/
+typedef struct {
+   void *body;
+   int size;
+} frsh_receive_endpoint_protocol_info_t;
+
+/**
+ * Algorithm used when the queue is full to choose the message to reject
+ **/
+typedef enum {
+    /** A new message is admitted rejecting the oldest message in the
+        queue to make room for the newcomer **/
+    FRSH_QRP_OLDEST,
+
+    /** Incoming messages are rejected if the queue is full **/
+    FRSH_QRP_NEWCOMER
+} frsh_queue_rejection_policy_t;
+
+/**
+ * Queing information for endpoints
+ **/
+typedef struct {
+    int queue_size;  /** Size 0 means that there is no queue **/
+    frsh_queue_rejection_policy_t queue_policy;
+} frsh_endpoint_queueing_info_t;
+
+
+typedef enum {
+    /** Network works OK **/
+    FRSH_ENS_UP,
+
+    /** Network is down **/
+    FRSH_ENS_DOWN
+} frsh_endpoint_network_status_t;
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif  /* !FRSH_DISTRIBUTED_TYPES_H_ */
diff --git a/src/frsh-include/frsh_dynamic_reclaiming.h b/src/frsh-include/frsh_dynamic_reclaiming.h
new file mode 100644 (file)
index 0000000..9f11c03
--- /dev/null
@@ -0,0 +1,84 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_dynamic_reclaiming.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_DYNAMIC_RECLAIMING_H_
+#define _FRSH_DYNAMIC_RECLAIMING_H_
+
+#include "frsh_core.h"
+
+/**
+ * @file frsh_dynamic_reclaiming.h
+ *
+ * If this define is activated, dynamic reclaimation will be used
+ * after spare capacity allocation.
+ **/
+
+
+#define FRSH_DYNAMIC_RECLAIMING_MODULE_SUPPORTED  1
+
+
+#endif // _FRSH_DYNAMIC_RECLAIMING_H_
diff --git a/src/frsh-include/frsh_energy_management.h b/src/frsh-include/frsh_energy_management.h
new file mode 100644 (file)
index 0000000..d1e5beb
--- /dev/null
@@ -0,0 +1,325 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_energy_management.h
+
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef  _FRSH_ENERGY_MANAGEMENT_H_
+#define  _FRSH_ENERGY_MANAGEMENT_H_
+
+#include <time.h>
+
+#include "frsh_energy_management_types.h"
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+#define FRSH_ENERGY_MANAGEMENT_MODULE_SUPPORTED       1
+
+/**
+ * @file frsh_energy_management.h
+ **/
+
+/**
+ * @defgroup energymgmnt Energy Management Module
+ *
+ * This module provides the ability to specify different budgets for
+ * different power levels.
+ *
+ * We model the situation by specifying budget values per power
+ * level.  Thus switching in the power-level would be done by changing
+ * the budget of the vres.  In all cases the period remains the same.
+ *
+ * All global FRSH contract operations (those done with the core
+ * module without specifying the power level) are considered to be
+ * applied to the higest power level, corresponding to a power_level_t
+ * value of 0.
+ *
+ * @note
+ * For all functions that operate on a contract, the resource is
+ * implicitly identified by the contract core parameters resource_type
+ * and resource_id that are either set through the
+ * frsh_contract_set_resource_and_label() function, or implicitly
+ * defined if no such call is made.
+ *
+ * @note
+ * For the power level management operations, only
+ * implementation for resource_type = FRSH_RT_PROCESSOR is mandatory,
+ * if the energy management module is present.
+ *
+ * @{
+ *
+ **/
+
+
+
+//////////////////////////////////////////////////////////////////////
+//           CONTRACT SERVICES
+//////////////////////////////////////////////////////////////////////
+
+
+/**
+ * frsh_contract_set_min_expiration()
+ * 
+ * This function sets the minimum battery expiration time that the
+ * system must be able to sustain without finishing battery power. A
+ * value of (0,0) would mean that the application does not have such
+ * requirement (this is the default if this parameter is not explicitly
+ * set).
+ **/
+int frsh_contract_set_min_expiration(frsh_contract_t *contract,
+                                    frsh_rel_time_t min_expiration);
+
+/**
+ * frsh_contract_get_min_expiration()
+ * 
+ * Get version of the previous function.
+ **/
+int frsh_contract_get_min_expiration(const frsh_contract_t *contract,
+                                    frsh_rel_time_t *min_expiration);
+
+/**
+ * frsh_contract_set_min_budget_pow()
+ *
+ * Here we specify the minimum budget value corresponding to a single
+ * power level.
+ *
+ * @param contract             The affected contract.
+ * @param power_level          The power level for which we are specifying the minimum budget.
+ * @param pow_min_budget       The minimum budget requested for the power level.
+ *
+ * @return 0 if no error \n
+ *     FRSH_ERR_BAD_ARGUMENT if power_level is greater than or equal to the value
+ *     returned by frsh_get_power_levels  budget value is not correct.
+ *
+ * @note
+ * If the minimum budget relative to one or more power levels has not been specified, then
+ * the framework may attempt to perform interpolation of the supplied values in
+ * order to infer them, if an accurate model for such operation is available.
+ * Otherwise, the contract is rejected at frsh_negotiate() time.
+ **/
+int frsh_contract_set_min_budget_pow(frsh_contract_t *contract,
+                                    frsh_power_level_t power_level,
+                                    const frsh_rel_time_t *pow_min_budget);
+
+/**
+ * frsh_contract_get_min_budget_pow()
+ *
+ * Get version of the previous function.
+ **/
+int frsh_contract_get_min_budget_pow(const frsh_contract_t *contract,
+                                    frsh_power_level_t power_level,
+                                    frsh_rel_time_t *pow_min_budget);
+
+/**
+ * frsh_contract_set_max_budget_pow()
+ *
+ * Here we specify the maximum budget for a single power level.
+ *
+ * @param contract             The affected contract object.
+ * @param power_level          The power level for which we are specifying the maximum budget.
+ * @param pow_max_budget       The maximum budget requested for the power level.
+ *
+ * @return 0 if no error \n
+ *        FRSH_ERR_BAD_ARGUMENT if any of the pointers is NULL or the
+ *             budget values don't go in ascending order.
+ *
+ **/
+int frsh_contract_set_max_budget_pow(frsh_contract_t *contract,
+                                    frsh_power_level_t power_level,
+                                    const frsh_rel_time_t *pow_max_budget);
+
+/**
+ * frsh_contract_get_max_budget_pow()
+ *
+ * Get version of the previous function.
+ **/
+int frsh_contract_get_max_budget_pow(const frsh_contract_t *contract,
+                                    frsh_power_level_t power_level,
+                                    frsh_rel_time_t *pow_max_budget);
+
+
+/**
+ * frsh_contract_set_utilization_pow()
+ *
+ * This function should be used for contracts with a period of
+ * discrete granularity.  Here we specify, for each allowed period,
+ * the budget to be used for each power level.
+ *
+ * @param contract     The affected contract object.
+ * @param power_level  The power level for which we specify budget and period.
+ * @param budget       The budget to be used for the supplied power level and period.
+ * @param period       One of the allowed periods (from the discrete set).
+ * @param period       The deadline used with the associated period (from the discrete set).
+ **/
+int frsh_contract_set_utilization_pow(frsh_contract_t *contract,
+                                     frsh_power_level_t power_level,
+                                     const frsh_rel_time_t *budget,
+                                     const frsh_rel_time_t *period,
+                                     const frsh_rel_time_t *deadline);
+
+/**
+ * frsh_contract_get_utilization_pow()
+ *
+ * Get version of the previous function.
+ **/
+int frsh_contract_get_utilization_pow(const frsh_contract_t *contract,
+                                     frsh_power_level_t power_level,
+                                     frsh_rel_time_t *budget,
+                                     frsh_rel_time_t *period,
+                                     frsh_rel_time_t *deadline);
+
+
+//////////////////////////////////////////////////////////////////////
+//           MANAGING THE POWER LEVEL
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * frsh_resource_set_power_level()
+ *
+ * Set the power level of the resource identified by the supplied type and id.
+ *
+ * @note
+ * Only implementation for resource_type = FRSH_RT_PROCESSOR is mandatory,
+ * if the energy management module is present.
+ **/
+int frsh_resource_set_power_level(frsh_resource_type_t resource_type,
+                                 frsh_resource_id_t resource_id,
+                                  frsh_power_level_t power_level);
+
+/**
+ * frsh_resource_get_power_level()
+ *
+ * Get version of the previous function.
+ **/
+int frsh_resource_get_power_level(frsh_resource_type_t resource_type,
+                                 frsh_resource_id_t resource_id,
+                                  frsh_power_level_t *power_level);
+
+/**
+ * frsh_resource_get_speed()
+ *
+ * Get in speed_ratio representative value for the speed of the specified
+ * resource, with respect to the maximum possible speed for such resource.
+ *
+ * @note
+ * Only implementation for resource_type = FRSH_RT_PROCESSOR is mandatory,
+ * if the energy management module is present.
+ **/
+int frsh_resource_get_speed(frsh_resource_type_t resource_type,
+                           frsh_resource_id_t resource_id,
+                           frsh_power_level_t power_level,
+                           double *speed_ratio);
+
+/**
+ * frsh_resource_get_num_power_levels()
+ *
+ * Get the number of power levels available for the resource identified
+ * by the supplied type and id.
+ *
+ * @note
+ * The power levels that may be used, for the identified resource,
+ * in other functions through a power_level_t type, range from 0
+ * to the value returned by this function minus 1.
+ *
+ * @note
+ * The power level 0 identifies the configuration with the maximum
+ * performance (and energy consumption) for the resource.
+ *
+ * @note
+ * Only implementation for resource_type = FRSH_RT_PROCESSOR is mandatory,
+ * if the energy management module is present.
+ */
+int frsh_resource_get_num_power_levels(frsh_resource_type_t resource_type,
+                                      frsh_resource_id_t resource_id,
+                                      int *num_power_levels);
+
+//////////////////////////////////////////////////////////////////////
+//           BATTERY EXPIRATION AND MANAGING POWER LEVELS
+//////////////////////////////////////////////////////////////////////
+
+/* /\** IS THIS NEEDED AT ALL ? I GUESS NOT - COMMENTED */
+/*  * frsh_resource_get_battery_expiration() */
+/*  * */
+/*  * Get the foreseen expiration time of the battery for the resource */
+/*  * identified by the supplied type and id. */
+/*  * */
+/* int frsh_battery_get_expiration(frsh_resource_type_t resource_type, */
+/*                              frsh_resource_id_t resource_id, */
+/*                              frsh_rel_time_t *expiration); */
+
+/**
+ * frsh_battery_get_expiration()
+ *
+ * Get the foreseen expiration time of the system battery(ies).
+ **/
+int frsh_battery_get_expiration(frsh_abs_time_t *expiration);
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif             /* _FRSH_ENERGY_MANAGEMENT_H_ */
diff --git a/src/frsh-include/frsh_energy_management_types.h b/src/frsh-include/frsh_energy_management_types.h
new file mode 100644 (file)
index 0000000..030e4fd
--- /dev/null
@@ -0,0 +1,118 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_energy_management_types.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef        FRSH_ENERGY_MANAGEMENT_TYPES_H_
+#define        FRSH_ENERGY_MANAGEMENT_TYPES_H_
+
+#include <time.h>
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_energy_management_types.h
+ **/
+
+/**
+ * @addtogroup energymgmnt
+ *
+ * @{
+ **/
+
+
+
+
+/**
+ * Here we define the different power levels.  They will be
+ * used as index to the budget arrays in energy management.
+ **/
+typedef enum {
+    FRSH_PLT_HIGH   = 0,
+    FRSH_PLT_MEDIUM = 1,
+    FRSH_PLT_LOW    = 2
+} frsh_power_level_t;
+
+
+/**
+ * Here we define a capacity specification for all power levels.
+ **/
+typedef struct {
+    frsh_rel_time_t budget[3];
+    frsh_rel_time_t period;
+} frsh_utilization_line_pow_t;
+
+/**
+ * Here we define the utilization set for different power levels
+ **/
+typedef struct {
+    int size;
+    frsh_utilization_line_pow_t utilizations[FRSH_MAX_N_UTILIZATION_VALUES];
+} frsh_utilization_set_pow_t;
+
+FRSH_CPP_END_DECLS
+
+#endif             /* !FRSH_ENERGY_MANAGEMENT_TYPES_H_ */
diff --git a/src/frsh-include/frsh_error.h b/src/frsh-include/frsh_error.h
new file mode 100644 (file)
index 0000000..47e4430
--- /dev/null
@@ -0,0 +1,277 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_error.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef        FRSH_ERROR_H_
+#define        FRSH_ERROR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file frsh_error.h
+ **/
+
+/**
+ * addtogroup core
+ *
+ * @{
+ **/
+
+/* Error codes */
+#define FRSH_NO_ERROR                            0
+
+#define FRSH_ERR_BASE_VALUE                      0x02004000
+
+#define FRSH_ERR_TOO_MANY_TASKS                  0x02004001
+#define FRSH_ERR_BAD_ARGUMENT                    0x02004002
+#define FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE        0x02004003
+#define FRSH_ERR_NO_RENEGOTIATION_REQUESTED      0x02004004
+#define FRSH_ERR_CONTRACT_REJECTED               0x02004005
+#define FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD    0x02004006
+#define FRSH_ERR_NOT_BOUND                       0x02004007
+#define FRSH_ERR_UNKNOWN_SCHEDULED_THREAD        0x02004008
+#define FRSH_ERR_NOT_CONTRACTED_VRES             0x02004009
+#define FRSH_ERR_NOT_SCHEDULED_THREAD            0x0200400A
+#define FRSH_ERR_TOO_MANY_SERVICE_JOBS           0x0200400B
+#define FRSH_ERR_TOO_MANY_SYNCH_OBJS             0x0200400C
+#define FRSH_ERR_TOO_MANY_VRES_IN_SYNCH_OBJ      0x0200400D
+#define FRSH_ERR_TOO_MANY_EVENTS_IN_SYNCH_OBJ    0x0200400E
+#define FRSH_ERR_INTERNAL_ERROR                  0x0200400F
+#define FRSH_ERR_TOO_MANY_VRES                   0x02004010
+#define FRSH_ERR_INVALID_SCHEDULER_REPLY         0x02004011
+#define FRSH_ERR_TOO_MANY_PENDING_REPLENISHMENTS 0x02004012
+#define FRSH_ERR_SYSTEM_ALREADY_INITIALIZED      0x02004013
+#define FRSH_ERR_SHARED_OBJ_ALREADY_INITIALIZED  0x02004014
+#define FRSH_ERR_SHARED_OBJ_NOT_INITIALIZED      0x02004015
+#define FRSH_ERR_SCHED_POLICY_NOT_COMPATIBLE     0x02004016
+#define FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE    0x02004017
+#define FRSH_ERR_ALREADY_BOUND                   0x02004018
+#define FRSH_ERR_RESOURCE_ID_INVALID             0x02004019
+#define FRSH_ERR_TOO_LARGE                       0x0200401A
+#define FRSH_ERR_BUFFER_FULL                     0x0200401B
+#define FRSH_ERR_NO_SPACE                        0x0200401C
+#define FRSH_ERR_NO_MESSAGES                     0x0200401D
+#define FRSH_WRN_MODULE_NOT_SUPPORTED            0x0200401E
+#define FRSH_ERR_NOT_INITIALIZED                 0x0200401F
+#define FRSH_ERR_TOO_MANY_SHARED_OBJS            0x02004020
+#define FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS   0x02004021
+#define FRSH_ERR_BUDGET_EXPIRED                  0x02004022
+#define FRSH_ERR_SHARED_OBJECT_NOT_PROTECTED     0x02004023
+#define FRSH_ERR_NOT_IMPLEMENTED                 0x02004024
+#define FRSH_ERR_CONTRACT_TYPE_NOT_COMPATIBLE    0x02004025
+#define FRSH_ERR_CAPACITY_NOT_DECREASING         0x02004026
+#define FRSH_ERR_CONTRACT_LABEL_UNKNOWN          0x02004027
+#define FRSH_ERR_OUT_OF_BUDGET                                  0x02004028
+#define FRSH_ERR_ALREADY_IN_FRSH                        0x02004029
+
+#define FRSH_ERR_LAST_VALUE                      0x02004030
+
+
+
+#ifdef AQuoSA
+#define my_frsh_perror(nn,ss) do { errno = nn; perror(ss); } while(0)
+#else
+#define my_frsh_perror(nn,ss) do { perror(ss); } while(0)
+#endif
+
+#define ERROR(nn,ss) do {if(nn>FRSH_ERR_BASE_VALUE) my_frsh_strerror(nn, ss); else { my_frsh_perror(nn, ss); } exit (nn);} while (0)
+
+
+int frsh_strerror (int error, char *message, size_t size);
+void my_frsh_strerror(int error, char *sss);
+
+/**
+ * This str_helper is needed to ensure argument expansion,
+ * see http://www.iar.com/p180591/p180591_eng.php
+ **/
+#define STR_HELPER(x) #x
+
+/**
+ * PERROR_FRESCOR
+ *
+ * This macro checks the given error number and composes a messages accordingly.
+ *
+ * @param nn  Error number
+ * @param ss  Error string (to be appended to FRSH or system error string)
+ **/
+#define PERROR_FRESCOR(_nn_,_ss_) do {         \
+ \
+        char error_string[1024]; \
+ \
+        sprintf(error_string,  "File: %s, in function %s at line %d, error %d: %s\n", __FILE__, __FUNCTION__, __LINE__, (_nn_), _ss_); \
+ \
+               if( (_nn_)>FRSH_ERR_BASE_VALUE ) {      \
+                       my_frsh_strerror( (_nn_), error_string);        \
+               } else {                                \
+                       my_frsh_perror(_nn_, error_string);    \
+               }                                       \
+} while(0)
+
+
+
+/**
+ * PERROR_AND_RETURN
+ *
+ * Macro that displays an error code and message and then returns from
+ * the current function
+ *
+ * @param nn  Error number
+ * @param ss  Error string (to be appended to FRSH or system error string)
+ **/
+#define PERROR_AND_RETURN(nn,ss) do {                  \
+        PERROR_FRESCOR(nn, ss); \
+               return (nn);                            \
+       } while (0)
+
+
+
+
+/**
+ * PERROR_AND_EXIT
+ *
+ * Macro that displays an error code and message and then aborts the
+ * program.
+ *
+ * @param nn  Error number
+ * @param ss  Error string (to be appended to FRSH or system error string)
+ **/
+#define PERROR_AND_EXIT(nn,ss) do {    \
+               PERROR_FRESCOR(nn,ss);          \
+               exit(nn);               \
+       } while (0)
+
+
+/**
+ * PRW:  Perror and Return Wrapper
+ *
+ * Function that calls funccall and checks the result != 0.
+ * In case of error it displays the error code with the function call
+ * as extra error string and returns from the function.
+ *
+ * terror (int) needs to be visible in the point of call.
+ *
+ * @param funccall Code to execute that should return 0 in a non error
+ *                 case.
+ **/
+#define PRW(funccall)  do { \
+  if ( (terror = funccall ) != 0) \
+  { \
+     PERROR_AND_RETURN( terror, STR_HELPER(funccall) ); \
+  } \
+} while(0)
+
+
+
+/**
+ * PXW:  Perror and eXit Wrapper
+ *
+ * Function that calls funccall and checks the result != 0.
+ * In case of error it displays the error code with the function call
+ * as extra error string and ABORTS the program.
+ *
+ * terror (int) needs to be visible in the point of call.
+ *
+ * @param funccall Code to execute that should return 0 in a non error
+ *                 case.
+ **/
+#define PXW(funccall)  do { \
+  if ( (terror = funccall ) != 0) \
+  { \
+     PERROR_AND_EXIT( terror, STR_HELPER(funccall) ); \
+  } \
+} while(0)
+
+
+
+/**
+ * PERROR_KERN_AND_EXIT
+ *
+ * Function that displays an error code and message and then aborts the
+ * program.
+ *
+ * @param nn  Error number
+ * @param ss  Error string (to be appended to FRSH or system error string)
+ **/
+#define PERROR_KERN_AND_EXIT(nn, ss) do {              \
+               errno = errno ? errno : (nn);           \
+               kern_printf(ss);                        \
+               exit(nn);                               \
+       } while (0)
+
+
+
+
+/*}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif             /* !FRSH_ERROR_H_ */
diff --git a/src/frsh-include/frsh_feedback_control.h b/src/frsh-include/frsh_feedback_control.h
new file mode 100644 (file)
index 0000000..d06fe75
--- /dev/null
@@ -0,0 +1,216 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_feedback_control.h
+
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef _FRSH_FEEDBACK_CONTROL_H_
+#define _FRSH_FEEDBACK_CONTROL_H_
+
+#include <time.h>
+
+//#include "frsh_feedback_control_types.h"
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+#define FRSH_FEEDBACKCTRL_MODULE_SUPPORTED       1
+
+/**
+ * @file frsh_feedback_control.h
+ **/
+
+/**
+ * @defgroup feedbackctrl Feedback Control Module
+ *
+ * This module provides a way to implement a QoS manager at the
+ * application level.
+ *
+ * @note
+ * Please, note that, in order to exploit the feedback-scheduling
+ * functionality of FRESCOR, an application needs to use a set of
+ * different functions:
+ * <ul>
+ *   <li>the frsh_contract_set_basic_params() and the
+ *       frsh_contract_set_reclamation_params() functions are used
+ *       to set the dynamic variability range (or options) for the budget;
+ *   <li>the frsh_feedback_set_spare() function is used to communicate to
+ *       the FMGR module what is the spare virtual resource that is used
+ *       to reserve a fraction of resource availability by FMGR-enabled
+ *       applications, so to avoid a complete occupation of the system
+ *       (this is needed in common cases if one wants to keep a good
+ *       performance of the QoS control loops);
+ *       such spare vres needs to have been previously negotiated through
+ *       the usual functions in the FRSH Core module;
+ *   <li>the frsh_feedback_set_desired_budget() function is used to
+ *       dynamically fine-tune the budget request for the application,
+ *       leaving to the FMGR module the freedom to fulfill the requests
+ *       made by all the applications in the system according to global
+ *       QoS control goals, as well as to the importance and weight
+ *       parameters that may be specified by the applications for individual
+ *       virtual resources.
+ * </ul>
+ *
+ * @{
+ *
+ **/
+
+/**
+ * frsh_feedback_set_spare()
+ *
+ * This function is used to tell the FRSH FEEDBACKCTRL module what is
+ * the spare contract that is used as a "reserve" of computation
+ * resources that may be used by other contracts making use of adaptive
+ * reservations.
+ *
+ * @note
+ * No threads must be ever attached to the contract identified by
+ * spare_id. If this happens, behaviour is unspecified.
+ *
+ * @note
+ * This function must be called only once. If it is called more than
+ * once, then the behaviour is unspecified.
+ **/
+int frsh_feedback_set_spare(const frsh_contract_t *spare_contract);
+
+/**
+ * frsh_feedback_get_spare()
+ *
+ * Get version of the frsh_feedback_set_spare() function.
+ **/
+int frsh_feedback_get_spare(frsh_contract_t *spare_contract);
+
+/**
+ * frsh_feedback_set_desired_budget()
+ *
+ * This function sets the budget request that would best suite the
+ * needs of the application for the very next server periods. The
+ * budget actually used for the vres instances (application jobs),
+ * that may be retrieved through a frsh_feedback_get_actual_budget() call,
+ * is dynamically changed by the FMGR Module, and may be less than
+ * the required value, as due to the following rules:
+ *
+ * <ul>
+ *   <li>if the required budget is less than the minimum guaranteed
+ *       negotiated for the vres, then it is always granted;
+ *   <li>if the set of requested budgets is schedulable, then all the
+ *       requests are granted, except for what stated in the note below;
+ *   <li>if the set of requested budgets overcomes the resource capacity
+ *       and the required budget is higher than the minimum guaranteed
+ *       negotiated for the vres, then the FMGR module makes an attempt to
+ *       fulfill the application request by using also the spare computation
+ *       resources that have been reserved through the
+ *       frsh_feedback_set_spare() call.
+ * </ul>
+ *
+ * Before any frsh_feedback_set_desired_budget() call, the desired budget
+ * is assumed to be equal to the maximum budget value set during contract
+ * negotiation.
+ *
+ * @note
+ * If the requested budget is higher than the maximum value negotiated
+ * for the vres, then an error is returned.
+ *
+ * @note
+ * The actual budget that is used for a vres may change dynamically
+ * and asynchronously with respect to the threads attached to the vres,
+ * due to other contracts being negotiated, renegotiated or terminated,
+ * or due the call of the frsh_feedback_set_desired_budget() function
+ * for other virtual resources.
+ *
+ * @param[in] p_budget_in
+ * The new budget to set as desired.
+ **/
+int frsh_feedback_set_desired_budget(frsh_vres_id_t vres_id, frsh_rel_time_t *p_budget_in);
+
+/**
+ * frsh_feedback_get_desired_budget()
+ *
+ * Get version of the frsh_feedback_set_desired_budget() function.
+ *
+ * @param[out] p_budget_out
+ * The last budget set as desired through a frsh_feedback_set_desired_budget()
+ * call, or the maximum budget set during contract negotiation, if no such
+ * call ever occurred.
+ **/
+int frsh_feedback_get_desired_budget(frsh_vres_id_t vres_id, frsh_rel_time_t *p_budget_out);
+
+/**
+ * frsh_feedback_get_actual_budget()
+ *
+ * Retrieve the actual budget that is being dynamically used by the FMGR module for
+ * the specified vres. The value returned by this function (in the budget parameter)
+ * for a given vres may change dynamically as a result of a call to the
+ * frsh_feedback_set_desired_budget() function for the same or other virtual resources.
+ **/
+int frsh_feedback_get_actual_budget(frsh_vres_id_t vres_id, frsh_rel_time_t *budget);
+
+/*@}*/
+
+
+FRSH_CPP_END_DECLS
+
+#endif
diff --git a/src/frsh-include/frsh_feedback_control_types.h b/src/frsh-include/frsh_feedback_control_types.h
new file mode 100644 (file)
index 0000000..6e90946
--- /dev/null
@@ -0,0 +1,97 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef        FRSH_FEEDBACK_CONTROL_TYPES_H_
+#define        FRSH_FEEDBACK_CONTROL_TYPES_H__
+
+#include <time.h>
+#include "frsh_opaque_types.h"
+#include "frsh_configuration_parameters.h"
+
+FRSH_CPP_BEGIN_DECLS
+/**
+ * @file frsh_feedback_control_types.h
+ **/
+
+/**
+ * @addtogroup feedbackctrl
+ *
+ * @{
+ **/
+
+/** 
+ * Integer type from 0 to 100 representing the percentage of spare
+ * capacity that will be allocated for feedbackctrl
+ **/
+typedef int frsh_spare_subset_t;
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif             /* !FRSH_FEEDBACK_CONTROL_TYPES_H_ */
diff --git a/src/frsh-include/frsh_hierarchical.h b/src/frsh-include/frsh_hierarchical.h
new file mode 100644 (file)
index 0000000..f04812f
--- /dev/null
@@ -0,0 +1,275 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_hierarchical.h
+
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_HIERARCHICAL_H_
+#define _FRSH_HIERARCHICAL_H_
+
+#include <time.h>
+#include "frsh_hierarchical_types.h"
+#include "frsh_core.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+#define FRSH_HIERARCHICAL_MODULE_SUPPORTED       1
+
+/**
+ * @file frsh_hierarchical.h
+ **/
+
+/**
+ * @defgroup hierarchical Hierarchical Scheduling Module
+ *
+ * This module includes the types and functions to use local
+ * schedulers within vres allowing to attach more than one thread
+ * to a vres and define an scheduling policy within.
+ * 
+ * @{
+ **/
+
+/**
+ * frsh_local_scheduler_init()
+ *
+ *  This call has the following effects:
+ *    FP:  none \n
+ *    EDF: none \n
+ *    TABLE_DRIVEN :
+ *       Records the schedule duration, and starts the
+ *       schedule at the time of the call. After the
+ *       schedule duration has elapsed, the schedule in
+ *       the table is repeated.
+ *
+ *  @return 0 if no error \n
+ *    FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range,
+ *      or info is NULL \n
+ *    FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under the FRSH \n
+ *    FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *    FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid
+ **/
+int frsh_local_scheduler_init(
+   frsh_vres_id_t       vres,
+   frsh_sched_init_info_t info);
+
+
+/**
+ * frsh_contract_set_sched_policy()
+ *
+ *  The operation updates the specified contract parameters object by
+ *  setting its scheduling policy to the specified input parameter.
+ *  The default policy is FRSH_NONE, which means that only one thread
+ *  may be bound to the vres
+ *
+ *  @return 0 if no error \n
+ *    FRSH_ERR_BAD_ARGUMENT : if sched_policy is not in range,
+ *     or contract is NULL
+ **/
+int frsh_contract_set_sched_policy
+  (frsh_contract_t *contract,
+   frsh_sched_policy_t         sched_policy);
+
+
+/**
+ * frsh_contract_get_sched_policy()
+ *
+ * This operation obtains from the specified contract parameters
+ * object its scheduling policy, and copies it to the place pointed to
+ * by the corresponding input parameter.
+ *
+ *  @return 0 if no error \n
+ *     FRSH_ERR_BAD_ARGUMENT : if sched_policy or contract are NULL
+ **/
+int frsh_contract_get_sched_policy
+  (const frsh_contract_t *contract,
+   frsh_sched_policy_t              *sched_policy);
+
+
+/**
+ * frsh_thread_create_local()
+ *
+ * This operation creates a thread and binds it to the specified
+ * vres, which must have a policy different than FRSH_NONE. The new
+ * thread is created with the arguments thread, attr, thread_code and
+ * arg as they are defined for the pthread_create() POSIX function
+ * call, and its local scheduling parameters are set to the value
+ * stored in the variable pointed to by sched_params, which must be
+ * compatible with the vres's scheduling policy. Then, the function
+ * binds the created thread to the new vres. The attr /parameter is
+ * overwritten as necessary to introduce the adequate scheduling
+ * policy and priority, according to the preemption level given in the
+ * contract and the frsh_priority_map() function defined by the user.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range,
+ *     or sched_params is NULL \n
+ *   FRSH_ERR_SCHED_POLICY_NOT_COMPATIBLE : if the scheduling policy 
+ *     in sched_params is not compatible to the vres's one \n
+ *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ *     main scheduler \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the referenced vres is not
+ *     valid \n
+ *   FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload
+ *     of the vres is FRSH_OVERHEAD \n
+ *   . 
+ *   It may also return any of  the errors that may be returned by the
+ *   pthread_create()POSIX function call
+ **/
+int frsh_thread_create_local(frsh_vres_id_t      vres,
+                             frsh_sched_params_t   *sched_params,
+                             frsh_thread_id_t             *thread,
+                             frsh_thread_attr_t        *attr,
+                             frsh_thread_code_t      thread_code,
+                             void                  *arg);
+
+/**
+ * frsh_thread_bind_local()
+ *
+ * This operation associates a thread with a vres, which must have a
+ * policy different than FRSH_NONE. The thread's local scheduling
+ * parameters are set to the value stored in the variable pointed to
+ * by sched_params, which must be compatible with the vres's
+ * scheduling policy. After the call the thread starts consuming the
+ * vres's budget and is executed according to the contract
+ * established for that vres and to its scheduling policy. If the
+ * thread was already bound to another vres, it is effectively
+ * unbound from it and bound to the specified one. 
+ *
+ * Implementation dependent issue: In order to allow the usage of
+ * application defined schedulers, the given thread must not have the
+ * scheduling policy SCHED_APP and at the same time be attached to an
+ * application scheduler different than the frsh scheduler. 
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the vres argument does not complain with
+ *     the expected format or valid range, the given thread does not exist,
+ *     or sched_params is NULL \n
+ *   FRSH_ERR_SCHED_POLICY_NOT_COMPATIBLE : if the scheduling policy 
+ *     in sched_params is not compatible to the vres's one. \n
+ *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ *     main scheduler \n
+ *   FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
+ *     an application defined scheduler different than the frsh
+ *     scheduler \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the referenced vres is not
+ *     valid \n
+ *   FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload
+ *     of the vres is FRSH_OVERHEAD
+ **/
+int frsh_thread_bind_local(frsh_vres_id_t      vres,
+                           frsh_thread_id_t            thread,
+                           frsh_sched_params_t  *sched_params);
+     
+
+/**
+ * frsh_thread_set_local_sched_params()
+ *
+ * This function changes the local scheduling parameters of the thread
+ * to the value pointed to by sched_params. This value must be
+ * compatible with the scheduling policy of the vres to which the
+ * thread is bound.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist,
+ *     or sched_params is NULL \n
+ *   FRSH_ERR_SCHED_POLICY_NOT_COMPATIBLE : if the thread is already bound
+ *     and the scheduling policy in sched_params is not compatible to the
+ *     one of the thread's vres. \n
+ *   FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled 
+ *     under FRSH \n
+ *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ *     main scheduler \n
+ *   FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
+ *     an application defined scheduler different than the frsh
+ *     scheduler \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the thread is bound and its vres
+ *     is not valid
+ **/
+int frsh_thread_set_local_sched_params (frsh_thread_id_t thread,
+                          const frsh_sched_params_t  *sched_params);
+
+/**
+ * frsh_thread_get_local_sched_params()
+ *
+ * This function stores the local scheduling parameters of the
+ * specified thread in the variable pointed to by sched_params.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if sched_params is NULL or the thread does
+ *      not exist \n
+ *   FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled 
+ *      under FRSH
+ **/
+int frsh_thread_get_local_sched_params(frsh_thread_id_t            thread,
+                                       frsh_sched_params_t  *sched_params);
+
+/*}*/
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_HIERARCHICAL_H_
diff --git a/src/frsh-include/frsh_hierarchical_types.h b/src/frsh-include/frsh_hierarchical_types.h
new file mode 100644 (file)
index 0000000..b230b4f
--- /dev/null
@@ -0,0 +1,141 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef        FRSH_HIERARCHICAL_TYPES_H_
+#define        FRSH_HIERARCHICAL_TYPES_H_
+
+/**
+ * @file frsh_hierarchical_types.h
+ **/
+
+#include <time.h>
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @addtogroup hierarchical
+ *
+ * @{
+ **/
+
+/** Scheduling policies **/
+typedef enum {FRSH_FP, FRSH_EDF, FRSH_TABLE_DRIVEN, FRSH_RR, FRSH_NONE} 
+    frsh_sched_policy_t;
+
+#define FRSH_DEFAULT_SCHED_POLICY        FRSH_NONE
+
+/**
+ * Scheduling policy and parameters
+ *
+ * The params member is a pointer to one of the 
+ * following:
+ *    FP:  int (priority)
+ *    EDF: frsh_rel_time_t (deadline)
+ *    RR:  none
+ *    TABLE_DRIVEN : struct frsh_table_driven_params_t
+ **/
+typedef struct {
+  frsh_sched_policy_t    policy;
+  void *                params;
+} frsh_sched_params_t;
+
+
+/**
+ * Scheduling parameters for the table-driven policy
+ * list of target windows 
+ **/
+typedef struct {
+   frsh_rel_time_t   start;
+   frsh_rel_time_t   end;
+   frsh_rel_time_t   comp_time;
+} frsh_target_window_t;
+
+/**
+ * Container for a frsh_target_window array
+ **/
+typedef struct {
+  int size;
+  frsh_target_window_t  table[FRSH_MAX_N_TARGET_WINDOWS];
+} frsh_table_driven_params_t;
+
+
+/**
+ * Initialization information for a scheduling policy
+ *
+ * It shall be one of the following:
+ *    FP:  none
+ *    EDF: none
+ *    RR: frsh_rel_time_t (slice duration)
+ *    TABLE_DRIVEN : frsh_rel_time_t (schedule duration)
+ **/
+typedef void * frsh_sched_init_info_t;
+
+/*}*/
+
+FRSH_CPP_END_DECLS
+
+#endif             /* !FRSH_HIERARCHICAL_TYPES_H_ */
diff --git a/src/frsh-include/frsh_implementation_specific.h b/src/frsh-include/frsh_implementation_specific.h
new file mode 100644 (file)
index 0000000..09ec563
--- /dev/null
@@ -0,0 +1,214 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_implementation_specific.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_IMPLEMENTATION_SPECIFIC_H_
+#define _FRSH_IMPLEMENTATION_SPECIFIC_H_
+
+#include "frsh_implementation_specific_types.h"
+#include "frsh_core.h"
+
+#define FRSH_IMPLEMENTATION_SPECIFIC_MODULE_SUPPORTED     1
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_implementation_specific.h
+ *
+ **/
+
+/**
+ * @defgroup implementationspec Implementation Specific module
+ *
+ * The operations defined in this module are of optional use. The
+ * intention is to provide better tunning options taking advantage of
+ * specific characteristics of the underlaying OS.
+ *
+ *
+ * e.g. being able to manually assign priorities assuming that the OS
+ * uses a fixed priority paradigm).
+ *
+ * @{
+ **/
+
+/**
+ * frsh_contract_set_preemption_level()
+ *
+ * The operation updates the specified contract parameters object by
+ * setting its preemption level to the specified input parameter.
+ *
+ * OBSERVATION: if this value is changed being any contract that
+ * uses the resource already accepted, the system's behavior and
+ * particularly the acceptance tests correctness are not garantee
+ * and probably wrong.
+ *
+ **/
+int frsh_contract_set_preemption_level
+  (frsh_contract_t     *contract,
+   frsh_preemption_level_t         preemption_level);
+
+
+/**
+ * frsh_contract_get_preemption_level()
+ *
+ * The operation obtains from the specified contract parameters object
+ * its preemption level and copies it to the place pointed to by the
+ * specified input parameter.
+ **/
+int frsh_contract_get_preemption_level
+      (const frsh_contract_t *contract,
+       frsh_preemption_level_t          *preemption_level);
+
+/**
+ * frsh_service_thread_set_preemption_level()
+ *
+ * This function sets the preemption level of the service thread to
+ * the specified value. The initial preemption level is a configurable
+ * parameter. This value is stored in a temporary variable and it is
+ * used the next time the service thread data is updated with the
+ * frsh_service_thread_set_data() function.
+ **/
+int frsh_service_thread_set_preemption_level
+      (frsh_preemption_level_t         preemption_level);
+
+/**
+ * frsh_service_thread_get_preemption_level()
+ *
+ * This function stores the current preemption level of the service
+ * thread in the variable pointed to by preemption_level
+ **/
+int frsh_service_thread_get_preemption_level
+        (frsh_preemption_level_t        *preemption_level);
+
+
+/**
+ * frsh_thread_exit()
+ *
+ * This operation shall terminate the calling thread, make the value
+ * value_ptr available to any successful join with the terminating
+ * thread, and unbind the thread from its associated vres. After
+ * cleaning up the thread management data, it is unbound and the
+ * scheduling policy is changed to fixed priority before the posix
+ * pthread_exit() function is called.
+ *
+ * There is a limitation in the current version of the
+ * MaRTE implementation that causes the information of a terminated
+ * thread to continue to be stored in the frsh scheduler, and the thread
+ * to continue to be counted in the number of threads. The
+ * frsh_thread_exit operation allows the implementation to delete the
+ * thread's information, and then terminate the thread. Therefore, it
+ * is recommended to use this function to terminate a thread under frsh.
+ *
+ * Implementation dependent issue: in the implementation with an
+ * application scheduler, after cleaning up the thread management
+ * data, it is unbound and the scheduling policy changed to fixed
+ * priority before calling the posix pthread_exit() function.
+ *
+ * NOTE:  This function, together with the internal function
+ *        frsh_internal_remove_thread()  has been removed from FRSH
+ *        because it shouldn't be necessary.
+ *
+ *        If there are some problems with MaRTE in thread termination
+ *        it should be fixed in the OS and not here.
+ *
+ * The function does not do anything special that is not done in the
+ * terminate callback of the FRSH scheduler.
+ *
+ * If you want to be curious about what the function did, look at the
+ * SVN repository (revision 273) or one of the past branches.
+ **/
+void frsh_thread_exit (void *value_ptr);
+
+
+/**
+ * frsh_sharedobj_set_preemption_level()
+ *
+ * The operation updates the specified shared object by setting its
+ * preemption level to the specified input parameter.
+ *
+ * OBSERVATION: if this value is changed being any contract that
+ * uses the resource already accepted, the system's behavior and
+ * particularly the acceptance tests correctness are not garantee
+ * and probably wrong.
+ **/
+int frsh_sharedobj_set_preemption_level(frsh_sharedobj_handle_t  obj_handle,
+                                     frsh_preemption_level_t   preemption_level);
+
+/**
+ * frsh_sharedobj_get_preemption_level()
+ *
+ * The operation obtains from the specified shared object its
+ * preemption level and copies it to the place pointed to by the
+ * specified input parameter.
+ **/
+int frsh_sharedobj_get_preemption_level(frsh_sharedobj_handle_t  obj_handle,
+                        frsh_preemption_level_t  *preemption_level);
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_IMPLEMENTATION_SPECIFIC_H_
diff --git a/src/frsh-include/frsh_implementation_specific_types.h b/src/frsh-include/frsh_implementation_specific_types.h
new file mode 100644 (file)
index 0000000..52c28ec
--- /dev/null
@@ -0,0 +1,92 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_implementation_specific_types.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef        FRSH_IMPLEMENTATION_SPECIFIC_TYPES_H_
+#define        FRSH_IMPLEMENTATION_SPECIFIC_TYPES_H_
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_implementation_specific_types.h
+ **/
+
+/**
+ * @addtogroup implementationspec
+ *
+ * @{
+ **/
+
+/** Implementation specific preemption level values **/
+typedef unsigned long frsh_preemption_level_t; // range 1..2**32-1
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+
+#endif             /* !FRSH_IMPLEMENTATION_SPECIFIC_TYPES_H_ */
diff --git a/src/frsh-include/frsh_memory_management.h b/src/frsh-include/frsh_memory_management.h
new file mode 100644 (file)
index 0000000..739ada8
--- /dev/null
@@ -0,0 +1,220 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_memory_management.h
+
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef _FRSH_MEMORY_MANAGEMENT_H_
+#define _FRSH_MEMORY_MANAGEMENT_H_
+
+#include "frsh_core_types.h"
+
+
+#define FRSH_MEMORY_MANAGEMENT_SUPPORTED 1
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_memory_management.h
+ **/
+
+/**
+ * @defgroup memmanagement Memory Management
+ *
+ * This module provides the types and the functions to add memory
+ * management support to FRSH contracts.
+ *
+ * @{
+ *
+ **/
+
+/**
+ * frsh_contract_set_min_memory()
+ *
+ * This function specifies in the contract the minimum
+ * memory needed by the application.
+ *
+ * @param[in] min_memory  Minimum needed memory in bytes.
+ * @param[in] max_memory  Maximum needed memory in bytes.
+ * @param  contract   Contract, in-out argument.
+ *
+ * @return 0 if no error \n
+ *     FRSH_ERR_BAD_ARGUMENT if min_memory <0
+ * 
+ **/
+int frsh_contract_set_min_memory(size_t min_memory,
+                                  frsh_contract_t *contract);
+
+/**
+ * frsh_contract_get_min_memory()
+ *
+ * This function gets the minimum memory parameter from the contract.
+ *
+ * @param[in] contract Contract object
+ * @param[out] min_memory  Placeholder for the minimum required
+ *                         memory.
+ *
+ * @return 0 if no error \n
+ *      FRSH_ERR_BAD_ARGUMENT if one of the pointers is NULL
+ **/
+int frsh_contract_get_min_memory(const frsh_contract_t *contract,
+                                  size_t *min_memory);
+
+// frsh_contract_set_max_memory() is new 
+// frsh_contract_get_max_memory() is new
+
+/**
+ * frsh_contract_set_max_memory()
+ *
+ * This function specifies in the contract the minimum
+ * memory needed by the application.
+ *
+ * @param[in] max_memory  Maximum needed memory in bytes.
+ * @param  contract   Contract, in-out argument.
+ *
+ *     FRSH_ERR_BAD_ARGUMENT if min_memory > max_memory
+ * 
+ **/
+int frsh_contract_set_max_memory(size_t max_memory,
+                                  frsh_contract_t *contract);
+
+
+/**
+ * frsh_contract_get_max_memory()
+ *
+ * This function gets the maximum memory parameter from the contract.
+ *
+ * @param[in] contract Contract object
+ * @param[out] max_memory  Placeholder for the maximum required
+ *                         memory.
+ *
+ * @return 0 if no error \n
+ *      FRSH_ERR_BAD_ARGUMENT if one of the pointers is NULL
+ **/
+int frsh_contract_get_max_memory(const frsh_contract_t *contract,
+                                  size_t *max_memory);
+
+
+/**
+ * frsh_vres_get_memory_info()
+ *
+ * This function gives us the runtime info of memory usage and
+ * reservation.
+ *
+ * @param[in] vres_id Identifier of vres
+ * @param[out] mem_allocated Memory currently allocated to the vres
+ * @param[out] mem_budget Total pool of memory reserved for the vres
+ *             (until next renegotiation).
+ *
+ * @return 0 if no error \n
+ *      FRSH_ERR_BAD_ARGUMENT if one of the pointers is NULL
+ **/ 
+int frsh_vres_get_memory_info(frsh_vres_id_t vres_id,
+                              size_t *mem_allocated,
+                              size_t *mem_budget);
+
+
+/**
+ * frsh_vres_memalloc()
+ *
+ * This function reserves some memory from the memory to this virtual
+ * resource. 
+ *
+ * @param[in] vres_id Identifier of vres.
+ * @param[in] Number of bytes
+ * @param[out] Valid pointer for the allocation
+ *
+ * @return 0 if no error \n
+ *      FRSH_ERR_BAD_ARGUMENT if the area pointer is NULL
+ *      FRSH_ERR_OUT_OF_BUDGET if no budget is available
+ **/
+int frsh_vres_malloc(frsh_vres_id_t vres_id,
+                     size_t num_bytes,
+                     void **area);
+
+/**
+ * frsh_vres_memfree()
+ *
+ * This function returns the previously allocated memory area for this
+ * virtual_resource to the main memory.
+ *
+ * @param[in] vres_id Identifier of vres.
+ * @param[in] area    Memory area to return
+ *
+ * @return 0 if no error \n
+ *      FRSH_ERR_BAD_ARGUMENT if the area pointer is NULL
+ **/
+int frsh_vres_memfree(frsh_vres_id_t vres_id,
+                      void *area);
+
+
+
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif             /* !FRSH_MEMORY_MANAGEMENT_H_ */
diff --git a/src/frsh-include/frsh_opaque_types.h b/src/frsh-include/frsh_opaque_types.h
new file mode 100644 (file)
index 0000000..55e802c
--- /dev/null
@@ -0,0 +1,241 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_opaque_types.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+// Implementation dependent definitions
+#ifndef _FRSH_OPAQUE_TYPES_H_
+#define _FRSH_OPAQUE_TYPES_H_
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_opaque_types.h
+ **/
+
+/**
+ * @defgroup opaque Opaque types
+ *
+ * This module specifies some #defines for privates types in the
+ * interface.  In this way we warn the FRSH user never to access the internal
+ * members of the types directly allowing us to change their internal
+ * definitions to suit our needs.
+ *
+ * Note that in Ada the FRSH user would never be allowed to access the
+ * members directly, however in C the compiler does not prevent this.
+ * But this is the best we can do in this language.
+ *
+ * @{
+ **/
+
+#define FRSH_VRES_ID_T_OPAQUE unsigned int
+
+/** frsh_contract_parameters_t **/
+#define FRSH_CONTRACT_T_OPAQUE struct { \
+\
+  /** Processor Id or Network Id **/                          \
+  frsh_resource_id_t   resource_id;                             \
+\
+  /** Whether processor or network **/                        \
+  frsh_resource_type_t resource_type;                           \
+\
+  /** Printable name for the contract
+     Unique within the local node               **/         \
+  frsh_contract_label_t      contract_label;                        \
+\
+  /** Minimum budget needed to perform a job.  With the energy
+      module this will be an array **/              \
+  frsh_rel_time_t         budget_min;                         \
+\
+  /** Maximum period that the system system can sustain **/   \
+  frsh_rel_time_t         period_max;                         \
+\
+  /** Maximum budget that the vres can use
+     (and would be happy to have).  With the energy module
+     this will be an array **/              \
+  frsh_rel_time_t         budget_max;                         \
+\
+  /** Minimum period for that
+     the system can use (and would be happy to have) **/     \
+  frsh_rel_time_t         period_min;                         \
+\
+  /** Set of discrete values for budget and period.  With the
+      energy module this will be an array **/        \
+  frsh_utilization_set_t   utilization_set;          \
+\
+  /** Workload_type:  bounded, indeterminate, overhead **/    \
+  frsh_workload_t          workload;                          \
+\
+  /** Scheduling type:  Regular, background
+     (in round-robin) or dummy             **/               \
+  frsh_contract_type_t    contract_type;                      \
+\
+  /** Whether delay equals period **/                         \
+  bool                    d_equals_t;                         \
+\
+  /** Deadline (will be ignored if d_equals_t is TRUE **/     \
+  frsh_rel_time_t         deadline;                           \
+\
+  /** Signal parameters for the case of
+      attempting to use too much budget       **/             \
+  frsh_signal_t           budget_overrun_signal;          \
+  frsh_signal_info_t      budget_overrun_siginfo;           \
+\
+  /** Signal parameters for the case a deadline
+     is missed **/                                           \
+  frsh_signal_t           deadline_miss_signal;           \
+  frsh_signal_info_t      deadline_miss_siginfo;            \
+\
+  /** Wether the range of period and budget is specified
+      in a continuous way (max-min) or as a set of
+      discrete values                                    **/  \
+  frsh_granularity_t       granularity;                       \
+\
+  /** Non-cooperative parameter for fair capacity
+      distribution                                **/         \
+  int                     importance;                \
+\
+  /** Cooperative parameter for fair capacity
+      distribution **/                                        \
+  int                     weight;                   \
+\
+  /** If > 0 it describes a duration for which
+      the allocated budget and capacity will be
+      maintained across negotiations  and will
+      not be affected for dynamic spare capacity    **/       \
+  frsh_rel_time_t         stability_time;  \
+\
+  /** Low level parameter related with the elegibility
+      preempt other threads                            **/    \
+  frsh_preemption_level_t  preemption_level;                  \
+\
+  /** Set of critical sections that the vres executes
+      besides the normal budget                        **/   \
+  frsh_csects_group_t critical_sections;                 \
+\
+  /** Internal scheduling policy within the vres for
+      hierarchical scheduling systems                  **/    \
+  frsh_sched_policy_t      policy;                            \
+\
+  /** Protocol info for distributed systems.  We store it
+      as a pointer+size.  It's internal meaning is imple-
+      mentation dependent.                              **/    \
+  frsh_protocol_info_t    protocol_info; \
+  frsh_endpoint_queueing_info_t    queueing_info; \
+\
+  /** Maximum loss rate
+      Percentage of packet loss in the network that is
+      tolerated by the application **/                       \
+int                     max_loss_rate; \
+\
+ /** Minimum memory size to be reserved **/ \
+size_t                  minimum_memory; \
+\
+/** Maximum memory size to be reserved  **/ \
+size_t                  maximum_memory; \
+}
+
+
+typedef int FRSH_SYNCHOBJ_HANDLE_T_OPAQUE;
+
+typedef int FRSH_SHAREDOBJ_HANDLE_T_OPAQUE;
+
+typedef unsigned int FRSH_GROUP_ID_T_OPAQUE;
+
+/**
+ * Critical section data
+ * - comon parameters
+ *     op_kind;     // kind of operation (READ or WRITE)
+ *     obj_handle;  // handle to shared object
+ *     wcet;        // Execution time
+ *     blocking;    // Blocking time (execution time + protection overheads)
+ * - attributes used only for protected shared objects
+ *     op;          // pointer to the operation
+ * - attributes used only for protected write operations
+ *     areas;       // memory areas to be protected
+ *
+ **/
+#define FRSH_CSECT_T_OPAQUE struct { \
+  frsh_csect_op_kind_t op_kind;                 \
+  frsh_sharedobj_handle_t obj_handle;               \
+  frsh_rel_time_t wcet;                              \
+  frsh_rel_time_t blocking;                              \
+  frsh_csect_op_t op;                           \
+  frsh_memory_areas_t areas;                         \
+  frsh_memory_areas_t storage;                         \
+}
+
+
+//opaque types for frsh endpoints
+typedef int FRSH_SEND_ENDPOINT_T_OPAQUE;
+
+typedef int FRSH_RECEIVE_ENDPOINT_T_OPAQUE;
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_OPAQUE_TYPES_H_
diff --git a/src/frsh-include/frsh_shared_objects.h b/src/frsh-include/frsh_shared_objects.h
new file mode 100644 (file)
index 0000000..cca6c15
--- /dev/null
@@ -0,0 +1,705 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_shared_objects.h
+
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef _FRSH_SHARED_OBJECTS_H_
+#define _FRSH_SHARED_OBJECTS_H_
+
+#include "frsh_shared_objects_types.h"
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+#define FRSH_SHAREDOBJS_MODULE_SUPPORTED       1
+
+/**
+ * @file frsh_shared_objects.h
+ **/
+
+/**
+ * @defgroup sharedobj Shared Objects module
+ *
+ * This module includes the functions to declare and use shared
+ * objects in different critical sections.
+ *
+ * A shared object is an abstraction of a mutex giving it a name and a
+ * possible priority ceiling.
+ *
+ * A critical section represents a usage of a shared object with a wcet.
+ * One or more critical sections can be included in a contract. 
+ *
+ * There are two types of shared_objects: protected and unprotected.
+ * 
+ * -  <b>UNPROTECTED shared objects</b>.  These shared objects are always
+ *    used in trusted critical sections for which the worst-case
+ *    execution times can be guaranteed not to be exceeded by the
+ *    application designer (eg because tools have been used to verify
+ *    the schedulability off-line).  Given these conditions, there is
+ *    no need to have a mechanism to monitor their execution time, with
+ *    the corresponding savings in overhead.
+ *
+ * -  <b>PROTECTED shared objects</b>.  For these shared objects a mechanism
+ *    may be used in one or more of their critical sections to monitor
+ *    and enforce their worst-case execution time.  These shared
+ *    objects are restricted to data in regular memory because a
+ *    mechanism to save and restore the state is necessary in order to
+ *    cleanly abort a misbehaving critical section.\n
+ *    
+ * Critical sections are categorized depending on wcet monitoring and
+ * rollback capability.
+ *
+ * - <b>UNCHECKED critical sections</b>.  These critical sections are
+ *   not monitored by FRSH for wcet compliance.  Their wcet value is
+ *   used only for analysis purposes (calculation of blocking times).
+ *
+ * - <b>READ critical sections</b>.  These critical sections have
+ *   their wcet enforced but they don't have any rollback action
+ *   applied when their wcet is exceeded.
+ *
+ * - <b>WRITE critical sections</b>.  These critical sections have
+ *   their wcet monitored and they have a rollback mechanism applied
+ *   to their memory areas prior to being aborted for exceeding their
+ *   declared wcet. 
+ *
+ * READ and WRITE critical sections must use PROTECTED shared objects,
+ * but UNCHECKED critical sections may use PROTECTED or UNPROTECTED
+ * shared objects.
+ *
+ * The monitoring mechanism for READ and WRITE critical section works
+ * by executing them indirectly via a registered callback function.
+ * UNCHECKED critical sections are executed directly by the
+ * application.
+ *
+ * The rollback mechanism for WRITE critical sections requires an
+ * additional registration of the memory areas that the callback
+ * function may modify.  With this data FRSH will do an initial saving
+ * of this areas that will used for restoration when there is a rollback
+ * operation.
+ *
+ * Note that extra time for the saving and the restoration must be
+ * included in the wcet specified for a WRITE critical section.
+ * Functions are provided to assist the developer in calculating this
+ * extra time.
+ *
+ * The reason for allowing the use of PROTECTED shared objects in
+ * UNCHECKED critical sections is to allow for legacy or trusted
+ * code that would use UNCHECKED critical sections to share a shared
+ * object with an untrusted code using READ or WRITE critical sections.
+ *
+ * This module makes use of the following constants defined in 
+ * frsh_configuration_parameters.h.  We list them with our proposed
+ * default values.
+ *
+ *        FRSH_MAX_N_SHARED_OBJECTS 100 \n
+ *        FRSH_MAX_N_CRITICAL_SECTIONS 20\n
+ *        FRSH_MAX_N_MEMORY_AREAS 4\n
+ * 
+ * @{
+ **/
+
+
+/////////////////////////////////////////////////////
+//           SHARED OBJECTS & OPERATIONS MANAGEMENT
+/////////////////////////////////////////////////////
+/**
+ * @defgroup so_opp_mgmnt Shared Objects & Operations
+ * @ingroup sharedobj
+ *
+ * These functions are used to declare shared objects and link them
+ * with a mutex.
+ * 
+ * @{
+ **/
+
+/**
+ * frsh_sharedobj_init()
+ *
+ * Initialization of shared objects. If the object identified by
+ * obj_label does not yet exist, it is created, a handle to the object is
+ * returned in the variable pointed to by obj_handle, and the
+ * specified mutex is initialized with the appropriate attributes
+ * necessary for the current implementation.  If the object already
+ * exists, the function fails. The object is created according to the
+ * kind of object (protected or unprotected) specified by obj_kind
+ *
+ * @param[in] obj_label  Label defined by the application.  Char * for
+ *                       a string of FRSH_MAX_SIZE_SHARED_OBJ_LABEL
+ *                       characters (+ null terminating \0).
+ *
+ * @param[in] obj_kind  Whether it is protected or unprotected.
+ *
+ * @param[out] obj_handle Placeholder for the shared object handle.
+ *
+ * @param[out] mutex  Placeholder for the mutex.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if obj_label, obj_handle, or mutex are NULL \n
+ *   FRSH_ERR_SHARED_OBJ_ALREADY_INITIALIZED : if the object identified
+ *      by label already exists \n
+ *   FRSH_ERR_TOO_MANY_SHARED_OBJS : if the number of already
+ *      initialized shared objects exceed the
+ *      FRSH_MAX_N_SHARED_OBJECTS configuration parameter. \n
+ *   .
+ *   It may also return any of the error codes that are returned by
+ *   fosa_mutex_init() and fosa_mutex_set_prioceiling().
+ * 
+ **/
+int frsh_sharedobj_init
+   (char      *obj_label,
+    frsh_sharedobj_kind_t   obj_kind,
+    frsh_sharedobj_handle_t *obj_handle,
+    frsh_mutex_t          *mutex);
+
+
+
+/**
+ * frsh_sharedobj_get_handle()
+ *
+ * Getting the handle of shared objects. If the object already exists
+ * a handle to the object is returned in the variable pointed to by
+ * obj_handle. Otherwise, an error code is returned.
+ *
+ * @param[in] obj_label  Defined by the application at object creation
+ *                time. Char * for a string of FRSH_MAX_SIZE_SHARED_OBJ_LABEL
+ *                characters (+ null terminating \0).
+ *
+ * @param[out] obj_handle Placeholder for the object handle.
+ *
+ * @return 0 if no error \n
+ *    FRSH_ERR_BAD_ARGUMENT : if label or obj_handle are NULL \n
+ *    FRSH_ERR_SHARED_OBJ_NOT_INITIALIZED : if the shared object identified
+ *        by obj_label does not exist \n
+ *    FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under FRSH \n
+ *    FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *    FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid \n
+ *   .
+ *   It may also return any of the error codes that are returned by the
+ *   fosa_mutex_init() function call
+ * 
+ **/
+int frsh_sharedobj_get_handle
+     (char *obj_label,
+      frsh_sharedobj_handle_t *obj_handle);
+
+
+/**
+ * frsh_sharedobj_get_mutex()
+ *
+ * Getting the mutex of shared objects.
+ *
+ * @param[in] obj_handle   Handle of the shared object
+ *
+ * @param[out] mutex  Placeholder for A POINTER to a pointer of the
+ *                    mutex. We give the pointer to discourage the
+ *                    application of using a local copy of the mutex.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
+ *      is not correct or reference a wrong shared object \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under the FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid
+ * 
+ **/
+int frsh_sharedobj_get_mutex
+   (frsh_sharedobj_handle_t  obj_handle,
+    frsh_mutex_t          **mutex);
+
+/**
+ * frsh_sharedobj_get_obj_kind()
+ *
+ * Get the object kind (protected/unprotected) of the object handle.
+ *
+ * @param[in] obj_handle   Handle of the shared object
+ *
+ * @param[out] obj_kind  Placeholder for an enumeration variable of
+ *                       protected / unprotected.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
+ *      is not correct or reference a wrong shared object \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under the FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid 
+ * 
+ **/
+int frsh_sharedobj_get_obj_kind
+   (frsh_sharedobj_handle_t  obj_handle,
+    frsh_sharedobj_kind_t   *obj_kind);
+
+/**
+ * frsh_sharedobj_remove()
+ *
+ * Allows the implementation to remove a shared object when the last
+ * vres referencing it is cancelled. This removes the object id and
+ * other internal data associated with the object, but does not remove
+ * the mutex; this is done by the application through the common POSIX
+ * API.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL or obj_handle
+ *      is not correct or references a wrong shared object \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under the FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid 
+ * 
+ **/
+int frsh_sharedobj_remove
+   (frsh_sharedobj_handle_t  obj_handle);
+
+
+
+/*@}*/
+
+/////////////////////////////////////////////////////
+//                       CRITICAL SECTIONS
+/////////////////////////////////////////////////////
+/**
+ * @defgroup so_critical Critical Sections
+ * @ingroup sharedobj
+ *
+ * These functions are used to create and manage the parameters
+ * of critical sections. Critical sections are operations that
+ * make use of a shared object in a mutually exclusive way.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_csect_init()
+ *
+ * Initialize the critical section pointed to by csect
+ * with a handle to its shared object, and the worst-case execution
+ * time.
+ *
+ * The operation_kind is set to FRSH_CSOK_UNCHECKED.
+ *
+ * @param[in] obj_handle  Shared object previously initialised.
+ *
+ * @param[in] wcet Execution time of the critical section.  This
+ *                 budget is consumed in parallel with the vres budget.
+ *
+ * @param[out] csect Critical section memory placeholder.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL \b or \n
+ *       obj_handle is not correct or references a wrong shared object \b or \n
+ *       if wcet  is in the wrong format for specifying a time interval value \n 
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under the FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid
+ * 
+ **/
+int frsh_csect_init
+    (frsh_sharedobj_handle_t obj_handle,
+     frsh_rel_time_t wcet,
+     frsh_csect_t *csect);
+
+
+/**
+ * frsh_csect_get_sharedobj_handle()
+ *
+ * Get in the variable pointed to by obj_handle the handle to the 
+ * shared object stored in the critical section referenced by csect
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if csect or obj_handle are NULL or csect
+ *      is not correct \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under the FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid
+ * 
+ **/
+int frsh_csect_get_sharedobj_handle
+    (const frsh_csect_t *csect,
+     frsh_sharedobj_handle_t * obj_handle);
+
+/**
+ * frsh_csect_get_wcet()
+ *
+ * Get in the variable pointed to by wcet the worst-case execution time
+ * of the operation stored in the critical section referenced by csect.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if csect or wcet are NULL or csect
+ *      is not correct \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid
+ * 
+ **/
+int frsh_csect_get_wcet
+    (const frsh_csect_t *csect,
+     frsh_rel_time_t *wcet);
+
+
+/**
+ * frsh_csect_register_read_op()
+ *
+ * Register the given operation with the critical section and set
+ * op_kind to FRSH_CSOK_READ.
+ *
+ * The function returns an error if the shared_object is unprotected.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if csect or op are NULL or if csect points
+ *      to a wrong critical section or if the shared_object is of type
+ *      unprotected. 
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid
+ * 
+ **/
+int frsh_csect_register_read_op
+    (frsh_csect_t *csect,
+     frsh_csect_op_t op);
+
+/**
+ * frsh_csect_register_write_op()
+ *
+ * Register the given operation with the critical section, register
+ * the memory areas and set op_kind to FRSH_CSOK_WRITE.
+ *
+ * If the memory areas are empty the functions returns an error.
+ *
+ * The function returns an error if the shared_object is unprotected.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if op, csect or areas are NULL or csect points 
+ *      to a wrong critical section, or areas has a wrong size, or if the 
+ *      shared_object of csect is of type unprotected.
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under the FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid
+ * 
+ **/
+int frsh_csect_register_write_op
+    (frsh_csect_t *csect,
+     frsh_csect_op_t op,
+     const frsh_memory_areas_t *areas);
+
+
+/**
+ * frsh_csect_get_op_kind()
+ *
+ * Returns the type of operation (read/write/unchecked) of the critical section.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if csect or op_kind are NULL or csect
+ *      is not correct \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid
+ * 
+ **/
+int frsh_csect_get_op_kind
+    (const frsh_csect_t *csect,
+     frsh_csect_op_kind_t *op_kind);
+
+
+/**
+ * frsh_csect_get_read_op()
+ *
+ * Get into the variable pointed to by op the operation pointer stored
+ * in the critical section referenced by csect.
+ *
+ * If the csect is of type write or unchecked it returns an error.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong 
+ *      critical section, or to a critical section that is not of the
+ *      FRSH_CSOK_READ kind \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid
+ * 
+ **/
+int frsh_csect_get_read_op
+    (const frsh_csect_t *csect,
+     frsh_csect_op_t *op);
+
+
+
+/**
+ * frsh_csect_get_write_op()
+ *
+ * Get the operation pointer and the memory areas stored in the csect.
+ *
+ * If the csect is of type read or unchecked.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong 
+ *      critical section, or to a critical section that is not of the
+ *      FRSH_CSOK_WRITE kind \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid \n
+ * 
+ **/
+int frsh_csect_get_write_op
+    (const frsh_csect_t *csect,
+     frsh_csect_op_t *op,
+     frsh_memory_areas_t *areas);
+
+
+/**
+ * frsh_csect_invoke()
+ *
+ * Invoke the registered operation in the critical section, with the pointers
+ * to the input and output parameters specified by input_arg and
+ * output arg.
+ *
+ * If the section is of type FRSH_CSOK_UNCHECKED, the function returns
+ * an error.
+ *
+ * For read operations, the mutex is locked, the csect budget is set equal
+ * to the wcet, the registered read operation is invoked, and then the
+ * mutex is unlocked; if the csect budget expires, the operation is
+ * interrupted, the mutex is unlocked, and the function returns with
+ * an error code.
+ *
+ * For write operations, the mutex is locked, the registered memory
+ * areas are backed up, the csect budget is set equal to the wcet, the
+ * registered write operation is called, and the mutex is unlocked. If
+ * the csect budget expires, the operation is interrupted, the backed-up
+ * memory areas are recovered, the mutex is unlocked, and the function
+ * returns with an error code. The blocking time suffered by higher
+ * priority tasks is at most the wcet of the operation plus the backup
+ * time plus the recovery time.
+ *
+ * If the shared object in the critical section is not protected it
+ * returns an error.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong 
+ *      critical section, or to a critical section that is unprotected \n
+ *   FRSH_ERR_BUDGET_EXPIRED : the csect budget expired and the protected 
+ *      operation was interrupted \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid
+ * 
+ **/
+int frsh_csect_invoke
+    (const frsh_csect_t *csect,
+     const void * input_arg, 
+     void * output_arg);
+
+/**
+ * frsh_csect_get_blocking_time()
+ *
+ * Get in the variable pointed to by blocking the maximum blocking
+ * time of the operation of the referenced protected critical section.
+ *
+ * For read or unchecked operations, the maximum blocking time is the wcet.
+ *
+ * For write operations, the maximum blocking time suffered by higher
+ * priority tasks is the wcet of the operation plus the backup time
+ * plus the recovery time.
+ *
+ * @return 0 if no error \n
+ *   FRSH_ERR_BAD_ARGUMENT : if csect or blocking are NULL or if csect
+ *      points to a wrong critical section, or to a critical section
+ *      that is unprotected \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *      scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *      running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread 
+ *      has been cancelled or it is not valid
+ * 
+ **/
+int frsh_csect_get_blocking_time
+    (const frsh_csect_t *csect,
+     frsh_rel_time_t *blocking);
+
+
+/**
+ * frsh_csect_destroy()
+ * 
+ * Destroy a critical section, deallocating all the resources that may
+ * have been allocated to it.
+ **/
+int frsh_csect_destroy
+   (frsh_csect_t *csect);
+
+/**
+ * frsh_csect_register_thread()
+ * 
+ * Register the calling thread for invoking time-protected critical
+ * sections via frsh_csect_invoke.
+ **/
+int frsh_csect_register_thread();
+
+/**
+ * frsh_csect_deregister_thread()
+ * 
+ * Deregister the calling thread from being able to invoke
+ * time-protected critical sections. This operation releases system
+ * resources that may have been allocated for the thread.
+ **/
+int frsh_csect_deregister_thread();
+
+
+
+/*@}*/ /* For so_critical group */
+
+
+/////////////////////////////////////////////////////
+//                       CONTRACT PARAMETERS
+/////////////////////////////////////////////////////
+/**
+ * @defgroup so_contract Shared Objects & Contract Parameters
+ * @ingroup sharedobj
+ *
+ * These functions are used to link shared objects to contracts via
+ * critical sections.
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_contract_set_csects()
+ *
+ * The operation updates the specified contract parameters object by
+ * setting its critical sections to the specified input parameter.
+ *
+ * @return 0 if no error \n
+ *    FRSH_ERR_BAD_ARGUMENT :  if any of the pointers is NULL or 
+ *    the size of the critical_sections structure is less than zero
+ *    or greater than FRSH_MAX_N_CRITICAL_SECTIONS
+ * 
+ **/
+int frsh_contract_set_csects
+  (frsh_contract_t     *contract,
+   const frsh_csects_group_t *critical_sections);
+
+/**
+ * frsh_contract_get_csects()
+ *
+ * The operation obtains from the specified contract parameters object
+ * its critical sections, and copies them to the places pointed to by
+ * the specified input parameter.  Only those critical_section_data
+ * records that are in use in the critical_sections structure are
+ * copied (according to its size field).
+ *
+ * @return 0 if no error \n
+ *    FRSH_ERR_BAD_ARGUMENT :  if any of the pointers is NULL
+ * 
+ **/
+int frsh_contract_get_csects
+      (const frsh_contract_t *contract,
+       frsh_csects_group_t    *critical_sections);
+
+/*@}*/ /* For so_contract group */
+
+/*@}*/ /* For shared_objects group */
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_SHARED_OBJECTS_H_
diff --git a/src/frsh-include/frsh_shared_objects_types.h b/src/frsh-include/frsh_shared_objects_types.h
new file mode 100644 (file)
index 0000000..1ca74c8
--- /dev/null
@@ -0,0 +1,162 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef        FRSH_SHARED_OBJECTS_TYPES_H_
+#define        FRSH_SHARED_OBJECTS_TYPES_H_
+
+#include <time.h>
+#include "frsh_core_types.h"
+#include "frsh_configuration_parameters.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_shared_objects_types.h
+ **/
+
+/**
+ * @addtogroup sharedobj
+ *
+ * @{
+ **/
+
+/** Mutex object.  Attributes are handled by FOSA **/
+typedef fosa_mutex_t frsh_mutex_t;
+
+
+/** 
+ *  Shared object handle:  It is an opaque type (i.e. the internal
+ *  structure of this data type is implementation dependent).
+ **/
+typedef FRSH_SHAREDOBJ_HANDLE_T_OPAQUE  frsh_sharedobj_handle_t; 
+
+/**
+ *  Shared object textual label
+ **/
+typedef char frsh_sharedobj_label_t[FRSH_MAX_SIZE_SHARED_OBJ_LABEL + 1];
+
+/**
+ * Kind of shared object: protected or unprotected
+ */
+typedef enum 
+  {FRSH_SOK_UNPROTECTED, FRSH_SOK_PROTECTED}
+frsh_sharedobj_kind_t;
+
+/**
+ * Kind of protected operation: read, write or unchecked
+ **/
+typedef enum 
+  {FRSH_CSOK_UNCHECKED, FRSH_CSOK_READ, FRSH_CSOK_WRITE} 
+frsh_csect_op_kind_t;                           
+
+/**
+ *  Pointer to protected operation, which takes a pointer to
+ *  the input parameters, and a pointer to the output 
+ *  parameters; the user is responsible for not exceeding the 
+ *  sizes of the respective input and output parameters data structures
+ */
+typedef void (*frsh_csect_op_t)
+          (const void * input_arg, void * output_arg);
+
+/**
+ *  A memory area
+ */
+typedef struct {
+  size_t size;
+  void * area;
+} frsh_memory_area_data_t;
+
+/** 
+ * Memory areas container 
+ **/
+typedef struct {
+    int size; // = 0
+    frsh_memory_area_data_t memory_areas[FRSH_MAX_N_MEMORY_AREAS];
+} frsh_memory_areas_t;
+
+
+/**
+ * Critical section data (opaque type)
+ **/
+typedef FRSH_CSECT_T_OPAQUE frsh_csect_t;
+
+
+/**
+ * Container of a group of critical sections, up to a maximum size
+ **/
+typedef struct {
+  int size;     // size of the group; initially=0
+  frsh_csect_t csects[FRSH_MAX_N_CRITICAL_SECTIONS]; // array of csect 
+} frsh_csects_group_t;
+
+/*@}*/
+
+
+FRSH_CPP_END_DECLS
+
+#endif             /* !FRSH_SHARED_OBJECTS_TYPES_H_ */
diff --git a/src/frsh-include/frsh_spare_capacity.h b/src/frsh-include/frsh_spare_capacity.h
new file mode 100644 (file)
index 0000000..443ea69
--- /dev/null
@@ -0,0 +1,368 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_spare_capacity.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_SPARE_CAPACITY_H_
+#define _FRSH_SPARE_CAPACITY_H_
+
+#include <time.h>
+#include <stdint.h>
+#include "frsh_spare_capacity_types.h"
+#include "frsh_core_types.h"
+#include "frsh_core.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_spare_capacity.h
+ **/
+
+#define FRSH_SPARE_CAPACITY_MODULE_SUPPORTED       1
+
+
+/**
+ * @file frsh_spare_capacity.h
+ *
+ * This file contains the function prototypes for the usage of
+ * spare capacity and dynamic reclamation.
+ **/
+
+/**
+ * @defgroup sparecapacity Spare Capacity module
+ *
+ * This module manages the partition of exceeding capacity at
+ * negotiation time between the vres that express their desire of
+ * optional requirements. 
+ *
+ * It works by:
+ *
+ * -  Allowing to define a range of budget and period instead of
+ *    giving WCET values only.  This range can be continuous or
+ *    discrete.
+ *
+ * -  Specifying a fairness measurement to compete with other vres in the
+ *    division of the share.
+ *
+ * -  Specifying a stability_time time for vres that need to have
+ *    a assigned capacity remain const during time (they would be
+ *    annoyed if their budget or period would change). 
+ *
+ * There are no specific negotiation calls because the algorithms used
+ * in the core module take already these min-max ranges into account.
+ *
+ * An operation is available for applications to ask for a stability
+ * period of a specified length. The framework will then return the
+ * total capacity (execution time budget and virtual resource period)
+ * that the application is guaranteed to receive in this stability
+ * period. The rationale for this service is that jobs may span a
+ * number of virtual resource periods, and need to have a guaranteed
+ * amount of capacity before they can choose a higher quality (longer
+ * execution time) method, when multiple methods are available. Also
+ * applications may require that the capacity provided to them and
+ * hence the quality of results produced remains consistent for a
+ * period of time, so that consistent behaviour is provided for the
+ * user (e.g. multimedia applications).
+ *
+ * Requesting a new stability period has the effect of cancelling any
+ * previous one. So a subsequent request for stability up to the same
+ * point in time could return a lower total capacity, if spare capacity
+ * re-allocation is in progress due to the admission of a new
+ * application. If a stability period expires without having explicitly
+ * set a new one, the system may decide to perform a reallocation of
+ * spare resources at that point, or may defer this decision to some
+ * future point in time when it is appropriate. In both cases, a new
+ * stability period will start when the new spare capacity assignment
+ * is in effect.
+ *
+ *
+ * NOTE:  When we talk here about "spare capacity" we mean STATIC extra
+ *        capacity at NEGOTIATION TIME.  This is the minimum capacity
+ *        that the vres will get based on contract negotiation.
+ *        This capacity is distributed based on the importance and
+ *        weight values and is known before-hand at the beginning of
+ *        a period.
+ *
+ *        Besides this extra capacity, there is the DYNAMIC extra
+ *        capacity that results at RUN TIME from earlier job endings of
+ *        bounded-workload vres.  This extra capacity can vary
+ *        between each execution period and is not known beforehand.
+ *
+ *        This extra run-time capacity is assigned if the following 2
+ *        conditions are met:
+ *
+ *        -  FRSH_DYNAMIC_RECLAIMING_MODULE_SUPPORTED is defined to 1
+ *            (in frsh_dynamic_reclaiming.h).
+ *
+ *        -  There is at least one vres willing to accept this extra
+ *           capacity: 
+ *           -  A FRSH_BOUNDED workload vres with a range of Budget
+ *              and Period that can absorb the extra capacity and
+ *              whose static_time period is not active.
+ *           -  An INDETERMINATE workload vres with an active
+ *              static_time period.
+ * @{
+ **/
+
+
+
+/**
+ * frsh_contract_set_reclamation_params()
+ *
+ * The operation updates the specified contract parameters object by
+ * setting its maximum usable budget, minimum period, granularity,
+ * utilization set, weight, and importance to the specified input
+ * parameters.
+ *
+ * @param contract  Contract object
+ * @param stability_time Time in which FRSH guarantees that the
+ *                   assigned budget and period will remain permanent
+ *                   even across renegotiations.
+ * @param budget_max The maximum budget that the vres aspires to
+ *                   get allocated.
+ * @param period_min The minimum period (therefore minimal
+ *                   interarrival time) that the vres may get for
+ *                   awakening and replenishment periods.
+ * @param granularity FRSH_CONTINUOUS:  Use  min-max values,
+ *                    FRSH_DISCRETE: Use utilization_set.
+ * @param utilization_set A structure of discrete triples (budget,
+ *                          period, deadline)
+ * @param importance non-cooperative urgency indicator.  Vres with
+ *                   higher importance will get all spare capacity des
+ * @param weight    cooperative urgency indicator.  At equal
+ *                   importance, spare capacity will be distributed
+ *                   proportionally to weight levels.
+ *
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if contract is NULL  \b or \n
+ *     (budget_max value is grater than period_max or smaller than budget_min) \b or \n
+ *      (period_min is smaller than budget_mint or larger than period_max)     \b or \n
+ *      (granularity is neither FRSH_CONTINUOUS nor FRSH_DISCRETE)     \b or \n
+ *      (granularity is FRSH_CONTINUOUS and 
+ *       utilization_set is not FRSH_NULL_UTILIZATION_SET)            \b or \n
+ *      (granularity is FRSH_DISCRETE and
+ *       utilization_set is FRSH_NULL_UTILIZATION_SET                 \b or \n
+ *      (utilization_set is not FRSH_NULL_UTILIZATION_SET and
+ *       (size of utilization_set less than 2 or greater 
+ *        than FRSH_MAX_N_UTILIZATION_VALUES)                )        \b or \n
+ *      (weight < 0)                                                  \b or \n
+ *      (importance is less than 1 or greater than FRSH_N_IMPORTANCE_LEVELS) \b or \n
+ *      (the utilization_set elements are not in increasing utilization order) \b or \n
+ *      (the first utilization value in the utilization_set does not match
+ *       the pair (budget_min, period_max) of the contract)           \b or \n
+ *      (the last utilization value in the utilization_set does not match
+ *       the pair (budget_max, period_min) of the contract)
+ * 
+ **/
+int frsh_contract_set_reclamation_params(frsh_contract_t   *contract,
+                                         const frsh_rel_time_t       *stability_time,
+                                         const frsh_rel_time_t       *budget_max,
+                                         const frsh_rel_time_t       *period_min,
+                                         frsh_granularity_t            granularity,
+                                         const frsh_utilization_set_t *utilization_set,
+                                         int                          importance,
+                                         int                          weight);
+
+/**
+ * frsh_contract_get_reclamation_params()
+ *
+ * The operation obtains the sparecapacity contract parameters from
+ * the contract object.
+ *
+ * @see frsh_set_contract_reclamation_parameters() for the meaning of
+ * each parameter.
+ * 
+ * Only the utilization_values of the utilization_set
+ * that are in use, are copied (according to its size field).
+ *
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT :  if contract is NULL
+ * 
+ **/
+int frsh_contract_get_reclamation_params
+  (const frsh_contract_t *contract,
+   frsh_rel_time_t                 *stability_time,
+   frsh_rel_time_t                 *budget_max,
+   frsh_rel_time_t                 *period_min,
+   frsh_granularity_t               *granularity,
+   frsh_utilization_set_t           *utilization_set,
+   int                             *importance,
+   int                             *weight);
+
+
+/**
+ * frsh_vres_get_remaining_stability_time()
+ *
+ * This operation returns the stability_time for the vres.
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
+ *       capacity is NULL \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *       scheduled under FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *       running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres has been cancelled or it
+ *       is not valid \n
+ * 
+ **/
+int frsh_vres_get_remaining_stability_time(frsh_vres_id_t vres, 
+                                      frsh_rel_time_t *stability_time);
+
+
+/**
+ * frsh_vres_set_stability_time: 
+ * 
+ * Dynamically set the stability time for a given virtual resource to
+ * the specified interval. This operation sets a new value for the
+ * stability time associated with the virtual resource. As a result of
+ * this call the system may change the allocation of resources to the
+ * current virtual resource. Regardless of whether the resources are
+ * reallocated or not, the call resets the stability period so that
+ * the level of resources allocated to the virtual resource is kept
+ * stable for at least the duration of the requested interval.  The
+ * possibly new values of budget and period are returned in the
+ * corresponding parameters
+ */
+
+int frsh_vres_set_stability_time 
+      (frsh_vres_id_t vres,
+       const frsh_rel_time_t *stability_time,
+       frsh_rel_time_t *budget,
+       frsh_rel_time_t *period);
+
+
+/**
+ * frsh_resource_get_capacity()
+ *
+ * This operation gets the spare capacity currently assigned to an
+ * importance level.  The capacity is the number obtained divided by
+ * UINT32_MAX, and it represents the processor or network
+ * utilization.
+ *
+ * @return 0 if successful \n
+ *   FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
+ *       capacity is NULL \n
+ *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *       scheduled under the FRSH \n
+ *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *       running \n
+ *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres has been cancelled or it
+ *       is not valid \n
+ * 
+ **/
+int frsh_resource_get_capacity(const frsh_resource_type_t resource_type,
+                               const frsh_resource_id_t resource_id,
+                               const int importance,
+                               uint32_t *capacity);
+
+
+/**
+ * frsh_resource_get_total_weight()
+ *
+ * This operation calculates the sum of the weight parameters for all
+ * vres in the system for a certain importance level at a specific
+ * resource_id.
+ *
+ * @return 0 if successful \n
+ *    FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
+ *       total_weight is NULL \n
+ *    FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ *       scheduled under FRSH \n
+ *    FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ *                    running \n
+ *    FRSH_ERR_NOT_CONTRACTED_VRES : if the vres has been cancelled or it
+ *       is not valid \n
+ **/
+int frsh_resource_get_total_weight 
+   (const frsh_resource_type_t resource_type,
+    const frsh_resource_id_t resource_id,
+    const int importance,
+    uint32_t *total_weight);
+
+
+/**
+ * frsh_vres_decrease_capacity()
+ *
+ * This operation is mainly intended for distributed systems but may
+ * also be useful for control application in uniprocessor systems.
+ *
+ * It allows the vres to ask for less budget and period that what he
+ * has actually received.  The request must be compatible with the
+ * rest of contract parameters.
+ *
+ **/
+int frsh_vres_decrease_capacity(frsh_vres_id_t vres,
+                           frsh_rel_time_t new_budget,
+                           frsh_rel_time_t new_period);
+
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_SPARE_CAPACITY_H_
diff --git a/src/frsh-include/frsh_spare_capacity_types.h b/src/frsh-include/frsh_spare_capacity_types.h
new file mode 100644 (file)
index 0000000..d51fc2c
--- /dev/null
@@ -0,0 +1,121 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_spare_capacity_types.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef        FRSH_SPARE_CAPACITY_TYPES_H_
+#define        FRSH_SPARE_CAPACITY_TYPES_H_
+
+#include <time.h>
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_spare_capacity_types.h
+ **/
+
+/**
+ * @addtogroup sparecapacity
+ *
+ * @{
+ **/
+
+/*************************/
+/* D E F I N I T I O N S */
+/*************************/
+
+/** Granularity of spare capacity requirements: continuous or discrete **/
+typedef enum {FRSH_GR_CONTINUOUS, FRSH_GR_DISCRETE} frsh_granularity_t;
+
+/** Utilization (C, T, and D) **/
+typedef struct {
+    frsh_rel_time_t    budget;    // Execution time
+    frsh_rel_time_t    period;    // Period
+    frsh_rel_time_t    deadline;  // Deadline
+} frsh_utilization_t;
+
+/** List of utilization values **/
+typedef struct {
+    int                      size; // = 0
+    frsh_utilization_t utilizations[FRSH_MAX_N_UTILIZATION_VALUES]; 
+} frsh_utilization_set_t;
+
+// Constants for assigning default values
+#define FRSH_DEFAULT_GRANULARITY         FRSH_GR_CONTINUOUS
+#define FRSH_DEFAULT_WEIGHT              1 // Cannot be zero with fsa_response_time
+#define FRSH_DEFAULT_IMPORTANCE          1
+
+// Constants for omitting the assignment of values to specific
+// arguments in calls to initialization functions
+#define FRSH_NULL_UTILIZATION_SET     \
+   (frsh_utilization_set_t *)NULL
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+
+#endif             /* !FRSH_SPARE_CAPACITY_TYPES_H_ */
diff --git a/src/frsh-include/frsh_thread_attrs.h b/src/frsh-include/frsh_thread_attrs.h
new file mode 100644 (file)
index 0000000..64882ac
--- /dev/null
@@ -0,0 +1,169 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_thread.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_THREADS_H_
+#define _FRSH_THREADS_H_
+
+#include "frsh_core_types.h"
+#include "frsh_core.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_thread_attrs.h
+ **/
+
+/**
+ * @defgroup threadfunc FRSH thread functions.
+ * @ingroup core
+ *
+ * These functions are used to manage frsh_thread_t and
+ * frsh_thread_attr_t used in the public API of FRSH.
+ *
+ * @{
+ **/
+
+
+/*************************
+ * Thread attributes
+ *************************/ 
+
+/**
+ * frsh_thread_attr_init()
+ *
+ * Initialize a thread attributes object
+ *
+ * This function initializes the object pointed to by attr to all 
+ * the default values defined by FRSH
+ *
+ * @return 0 if successful; otherwise it returns \n
+ *   FOSA_ENOMEM: insufficient memory exists to initialize the thread 
+ *           attributes object
+ **/
+static inline int frsh_thread_attr_init(frsh_thread_attr_t *attr)
+{
+    return fosa_thread_attr_init(attr);
+}
+
+/**
+ * frsh_thread_attr_destroy()
+ *
+ * Destroy a thread attributes object
+ *
+ * This function is used to destroy the thread attributes object,
+ * pointed to by attr, and deallocate any system resources allocated for it
+ * 
+ * Returns 0
+ */
+static inline int frsh_thread_attr_destroy(frsh_thread_attr_t *attr)
+{
+    return fosa_thread_attr_destroy(attr);
+}
+
+/**
+ * frsh_thread_attr_set_stacksize()
+ *
+ * Set the thread minimum stack size in a thread attributes object
+ *
+ * This function sets the minimum stack size of the thread attributes
+ * object attr to the value given by stacksize, in bytes. This
+ * function has no runtime effect on the stack size, except when the
+ * attributes object is used to create a thread, when it will be
+ * created with the specified minimum stack size
+ * 
+ * @return 0 if successful, or the following error code:
+ *    FOSA_EINVAL: the specified stacksize  value is not supported in
+ *            this implementation
+ */
+static inline int frsh_thread_attr_set_stacksize(frsh_thread_attr_t *attr, size_t stacksize)
+{
+    return fosa_thread_attr_set_stacksize(attr, stacksize);
+}
+
+/**
+ * frsh_thread_attr_get_stacksize()
+ *
+ * Get the thread minimum stack size from a thread attributes object
+ *
+ * This function sets the variable pointed to by stacksize to the
+ * minimum stack size stored in the thread attributes object attr.
+ * 
+ * @return 0
+ */
+static inline int frsh_thread_attr_get_stacksize
+      (const frsh_thread_attr_t *attr, size_t *stacksize)
+{
+    return fosa_thread_attr_get_stacksize(attr, stacksize);
+}
+
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+#endif
+
diff --git a/src/frsh-include/frsh_time.h b/src/frsh-include/frsh_time.h
new file mode 100644 (file)
index 0000000..8ab5f63
--- /dev/null
@@ -0,0 +1,413 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_spare_capacity_types.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      // 
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef        FRSH_TIME_H_
+#define        FRSH_TIME_H_
+
+#include "frsh_core_types.h"
+#include "frsh_core.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_time.h
+ **/
+
+
+/**
+ * \addtogroup core
+ **/
+/*@{*/
+
+/***********************
+ * Relational operations
+ ***********************/  
+
+/**
+ * frsh_abs_time_smaller()
+ *
+ * Check if an absolute time is smaller than another one.
+ **/
+static inline bool frsh_abs_time_smaller(frsh_abs_time_t t1, frsh_abs_time_t t2)
+{
+    return fosa_abs_time_smaller(t1, t2);
+}
+
+/**
+ * frsh_rel_time_smaller()
+ *
+ * Check if a relative interval is smaller than another one.
+ **/
+static inline bool frsh_rel_time_smaller(frsh_rel_time_t t1, frsh_rel_time_t t2)
+{
+    return fosa_rel_time_smaller(t1, t2);
+}
+
+/**
+ * frsh_abs_time_smaller_or_equal()
+ *
+ * Check if an absolute time is smaller than or equal to another one.
+ **/
+static inline bool frsh_abs_time_smaller_or_equal(frsh_abs_time_t t1, frsh_abs_time_t t2)
+{
+    return fosa_abs_time_smaller_or_equal(t1, t2);
+}
+
+/**
+ * frsh_rel_time_smaller_or_equal()
+ *
+ * Check if a relative interval is smaller than or equal to another one.
+ **/
+static inline bool frsh_rel_time_smaller_or_equal(frsh_rel_time_t t1, frsh_rel_time_t t2)
+{
+    return fosa_rel_time_smaller_or_equal(t1, t2);
+}
+
+
+/***********************
+ * Arithmetic operations
+ ***********************/  
+
+/**
+ * frsh_abs_time_incr()
+ *
+ * Add a relative interval to an absolute time.
+ */
+static inline frsh_abs_time_t frsh_abs_time_incr(frsh_abs_time_t base, frsh_rel_time_t interval)
+{
+    return fosa_abs_time_incr(base, interval);
+}
+
+/**
+ * frsh_rel_time_add()
+ *
+ * Add a relative interval to another one.
+ */
+static inline frsh_rel_time_t frsh_rel_time_add(frsh_rel_time_t t1, frsh_rel_time_t t2)
+{
+    return fosa_rel_time_add(t1, t2);
+}
+
+static inline frsh_rel_time_t frsh_rel_time_incr(frsh_rel_time_t t1, frsh_rel_time_t t2)
+{
+    return fosa_rel_time_add(t1, t2);
+}
+
+
+
+
+/**
+ * frsh_abs_time_decr
+ *
+ * Subtract a relative interval from an absolute time.
+ */
+static inline frsh_abs_time_t frsh_abs_time_decr(frsh_abs_time_t time, frsh_rel_time_t interval)
+{
+    return fosa_abs_time_decr(time, interval);
+}
+
+/**
+ * frsh_rel_time_decr()
+ *
+ * Subtract a relative interval from another one.
+ */
+static inline frsh_rel_time_t frsh_rel_time_decr(frsh_rel_time_t total, frsh_rel_time_t part)
+{
+    return fosa_rel_time_decr(total, part);
+}
+    
+
+/**
+ * frsh_abs_time_extract_interval()
+ * 
+ * Subtract two absolute times to get a relative interval.
+ */
+static inline frsh_rel_time_t frsh_abs_time_extract_interval(frsh_abs_time_t past, frsh_abs_time_t future)
+{
+    return fosa_abs_time_extract_interval(past, future);
+}
+
+
+static inline frsh_rel_time_t frsh_abs_time_subtract(frsh_abs_time_t past, frsh_abs_time_t future)
+{
+    return fosa_abs_time_extract_interval(past, future);
+}
+
+
+
+
+/**
+ * frsh_rel_time_times_integer()
+ * 
+ * Multiplies a relative time by an integer
+ */
+static inline frsh_rel_time_t frsh_rel_time_times_integer(frsh_rel_time_t time, long multiplier)
+{
+    return fosa_rel_time_times_integer(time, multiplier);
+}
+
+/**
+ * frsh_rel_time_times_integer()
+ * 
+ * Divides a relative time by an integer
+ **/
+static inline frsh_rel_time_t frsh_rel_time_divided_by_integer(frsh_rel_time_t time, long divider)
+{
+    return fosa_rel_time_divided_by_integer(time, divider);
+}
+
+
+/************************************
+ * Conversion to-from natural formats
+ * Note: Overflows may occur
+ ************************************/
+
+/**
+ * frsh_msec_to_rel_time()
+ *
+ * Convert an integer value of milliseconds into a relative time interval.
+ */
+static inline frsh_rel_time_t frsh_msec_to_rel_time(long msec)
+{
+    return fosa_msec_to_rel_time(msec);
+}
+
+/**
+ * frsh_rel_time_to_msec()
+ *
+ * Convert a relative interval into an integer number of milliseconds.
+ */
+static inline long frsh_rel_time_to_msec(frsh_rel_time_t interval)
+{
+    return fosa_rel_time_to_msec(interval);
+}
+
+/**
+ * frsh_msec_to_abs_time()
+ *
+ * Convert an integer value of milliseconds into an absolute time instant
+ */
+static inline frsh_abs_time_t frsh_msec_to_abs_time(long msec)
+{
+    return fosa_msec_to_abs_time(msec);
+}
+
+/**
+ * frsh_abs_time_to_msec()
+ *
+ * Convert an absolute instant into an integer number of milliseconds.
+ */
+static inline long frsh_abs_time_to_msec(frsh_abs_time_t instant)
+{
+    return fosa_abs_time_to_msec(instant);
+}
+
+/**
+ * frsh_usec_to_rel_time() 
+ *
+ * Convert an integer value of microseconds into an absolute instant.
+ */
+static inline frsh_rel_time_t frsh_usec_to_rel_time(long usec)
+{
+    return fosa_usec_to_rel_time(usec);
+}
+
+
+/**
+ * frsh_rel_time_to_usec() 
+ *
+ * Convert a relative interval into an integer number of microseconds.
+ */
+static inline long frsh_rel_time_to_usec(frsh_rel_time_t interval)
+{
+    return fosa_rel_time_to_usec(interval);
+}
+
+/**
+ * frsh_usec_to_abs_time() 
+ *
+ * Convert an integer value of microseconds into an absolute instant.
+ */
+static inline frsh_abs_time_t frsh_usec_to_abs_time(long usec)
+{
+    return fosa_usec_to_abs_time(usec);
+}
+
+
+/**
+ * frsh_abs_time_to_usec() 
+ *
+ * Convert a relative interval into an integer number of microseconds.
+ */
+static inline long frsh_abs_time_to_usec(frsh_abs_time_t interval)
+{
+    return fosa_abs_time_to_usec(interval);
+}
+
+/**
+ * frsh_nsec_to_rel_time() 
+ *
+ * Convert an integer value of microseconds into an absolute instant.
+ */
+static inline frsh_rel_time_t frsh_nsec_to_rel_time(long nsec)
+{
+    return fosa_nsec_to_rel_time(nsec);
+}
+
+
+/**
+ * frsh_rel_time_to_nsec() 
+ *
+ * Convert a relative interval into an integer number of microseconds.
+ */
+static inline long frsh_rel_time_to_nsec(frsh_rel_time_t interval)
+{
+    return fosa_rel_time_to_nsec(interval);
+}
+
+/**
+ * frsh_nsec_to_abs_time() 
+ *
+ * Convert an integer value of microseconds into an absolute instant.
+ */
+static inline frsh_abs_time_t frsh_nsec_to_abs_time(long nsec)
+{
+    return fosa_nsec_to_abs_time(nsec);
+}
+
+
+/**
+ * frsh_abs_time_to_nsec() 
+ *
+ * Convert a relative interval into an integer number of microseconds.
+ */
+static inline long frsh_abs_time_to_nsec(frsh_abs_time_t interval)
+{
+    return fosa_abs_time_to_nsec(interval);
+}
+
+/******************************************
+ * Conversion to-from POSIX timespec format
+ ******************************************/
+
+/**
+ * frsh_timespec_to_rel_time()
+ * 
+ * Convert a POSIX timespec value into a relative time interval.
+ */
+static inline frsh_rel_time_t frsh_timespec_to_rel_time(struct timespec interval)
+{
+    return fosa_timespec_to_rel_time(interval);
+}
+
+/**
+ * frsh_rel_time_to_timespec() 
+ *
+ * Convert a relative interval into a POSIX timespec value.
+ */
+static inline struct timespec frsh_rel_time_to_timespec(frsh_rel_time_t interval)
+{
+    return fosa_rel_time_to_timespec(interval);
+}
+
+/**
+ * frsh_timespec_to_abs_time()
+ * 
+ * Convert a POSIX timespec value into an absolute time.
+ */
+static inline frsh_abs_time_t frsh_timespec_to_abs_time(struct timespec time)
+{
+    return fosa_timespec_to_abs_time(time);
+}
+
+/**
+ * frsh_abs_time_to_timespec()
+ * 
+ * Convert an absolute time into a POSIX timespec value.
+ */
+static inline struct timespec frsh_abs_time_to_timespec(frsh_abs_time_t time)
+{
+    return fosa_abs_time_to_timespec(time);
+}
+
+
+/**
+ * frsh_eat()
+ *
+ * Keep the thread busy executing for a given period of time.
+ **/
+static inline void  frsh_eat(frsh_rel_time_t *cpu_time)
+{
+    fosa_eat(cpu_time);
+}
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif             /* !FOSA_TIME_H_ */
diff --git a/src/frsh-include/frsh_time_types.h b/src/frsh-include/frsh_time_types.h
new file mode 100644 (file)
index 0000000..9a8c4b2
--- /dev/null
@@ -0,0 +1,91 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  Valencia,           SPAIN
+//    Czech Technical University in Prague,  CZECH REPUBLIC
+//    ENEA                                   SWEDEN
+//    Thales Communication S.A.              FRANCE
+//    Visual Tools S.A.                      SPAIN
+//    Rapita Systems Ltd                     UK
+//    Evidence                               ITALY
+//
+//    See http://www.frescor.org for a link to partners' websites
+//
+//           FRESCOR project (FP6/2005/IST/5-034026) is funded
+//        in part by the European Union Sixth Framework Programme
+//        The European Union is not liable of any use that may be
+//        made of this code.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FRSH (FRescor ScHeduler)
+//
+//  FRSH is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FRSH is distributed in the hope that it will be
+//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+//  General Public License for more details. You should have received a
+//  copy of the GNU General Public License along with FRSH; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FRSH header files in a file,
+//  instantiating FRSH generics or templates, or linking other files
+//  with FRSH objects to produce an executable application, does not
+//  by itself cause the resulting executable application to be covered
+//  by the GNU General Public License. This exception does not
+//  however invalidate any other reasons why the executable file might be
+//  covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_spare_capacity_types.h
+//==============================================
+//  ******** *******    ********  **      **
+//  **///// /**////**  **//////  /**     /**
+//  **      /**   /** /**        /**     /**
+//  ******* /*******  /********* /**********
+//  **////  /**///**  ////////** /**//////**
+//  **      /**  //**        /** /**     /**
+//  **      /**   //** ********  /**     /**
+//  //       //     // ////////   //      //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef        FRSH_TIME_TYPES_H_
+#define        FRSH_TIME_TYPES_H_
+
+#include <fosa_types.h>
+
+/**
+ * @file frsh_time_types.h
+ **/
+
+
+/**
+ * \addtogroup core
+ **/
+/*@{*/
+
+/** the time types shall have assignment and equal operators **/
+typedef fosa_abs_time_t frsh_abs_time_t;
+typedef fosa_rel_time_t frsh_rel_time_t;
+
+
+/*@}*/
+
+#endif             /* !FRSH_TIME_TYPES_H_ */
diff --git a/src/frsh-include/frsh_transaction.h b/src/frsh-include/frsh_transaction.h
new file mode 100644 (file)
index 0000000..3b81ebd
--- /dev/null
@@ -0,0 +1,140 @@
+/**************************************************************************/
+/* Copyright (C) 2010 Czech Technical University in Prague               */
+/*                                                                       */
+/*  This file is part of FRSH (FRescor ScHeduler)                        */
+/*                                                                       */
+/* FRSH is free software; you can redistribute it and/or modify it       */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FRSH is distributed in the hope that it will be       */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FRSH; see file      */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FRSH header files in a file,        */
+/* instantiating FRSH generics or templates, or linking other files      */
+/* with FRSH objects to produce an executable application, does not      */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+
+#ifndef _FRSH_TRANSACTION_H_
+#define _FRSH_TRANSACTION_H_
+
+#include "frsh_cpp_macros.h"
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+struct fres_transaction_t_type;
+
+/* frsh_transaction_t is a pointer to resemble how frsh_contract_t is
+ * defined. */
+typedef struct fres_transaction_t_type *frsh_transaction_t;
+
+/** 
+ * Initialize a transaction.
+ * 
+ * @param transaction
+ * 
+ * @param name The name of the transaction which can be used in
+ * frsh_transaction_wait_for_name().
+ * 
+ * @return Zero on success, non-zero error code on return.
+ */
+int
+frsh_transaction_init(frsh_transaction_t *transaction,
+                     char *name);
+
+/** 
+ * Deallocates memory of the transaction object.
+ * 
+ * @param transaction 
+ */
+void
+frsh_transaction_destroy(frsh_transaction_t *transaction);
+
+/** 
+ * Add a contract to the transaction.
+ * 
+ * @param transaction Transaction
+ * @param contract Contract to add
+ * 
+ * @param index Index of the contract within the transaction. The
+ * index is used in frsh_transaction_alloc_vres(). The first added
+ * contract must have zero index, the second one, etc.
+ * 
+ * @return Zero on success, non-zero error code on return.
+ */
+int
+frsh_transaction_add_contract(frsh_transaction_t *transaction,
+                             frsh_contract_t *contract,
+                             int index);
+
+/** 
+ * Negotiates a multi-resource transaction.
+ *
+ * No resource is allocated in this step of negotiation. Use
+ * frsh_transaction_alloc_vres() to allocate resource and use it in
+ * application.
+ * 
+ * @param trans Transaction with added contracts.
+ * 
+ * @return Zero on success, non-zero error code on return.
+ */
+int
+frsh_transaction_negotiate(frsh_transaction_t *trans);
+
+/** 
+ * Cancels a negotiated transaction.
+ * 
+ * @param trans 
+ * 
+ * @return Zero on success, non-zero error code on return.
+ */
+int
+frsh_transaction_cancel(frsh_transaction_t *trans);
+
+/** 
+ * Retrieves a negotiated transaction by name.
+ *
+ * Applications that do not initiate transaction negotiation need a
+ * way to participate in the transaction. This function waits until
+ * the transaction with a given @a name is negotiated and then returns
+ * the @a transaction object.
+ * 
+ * @param name 
+ * @param transaction
+ * 
+ * @return Zero on success, non-zero error code on return.
+ */
+int
+frsh_transaction_wait_for_name(frsh_transaction_t *transaction,
+                              const char *name);
+/** 
+ * Allocates VRES from the negotiated transaction.
+ *
+ * Given the transaction object and an index (see
+ * frsh_transaction_add_contract()) this function requests allocation
+ * of the
+ * 
+ * @param t 
+ * @param vres 
+ * @param index
+ * 
+ * @return 
+ */
+int
+frsh_transaction_alloc_vres(frsh_transaction_t *t,
+                           int index,
+                           frsh_vres_id_t *vres);
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_TRANSACTION_H_
diff --git a/src/fwp/.gitignore b/src/fwp/.gitignore
new file mode 100644 (file)
index 0000000..110f125
--- /dev/null
@@ -0,0 +1,6 @@
+_build
+_compiled
+TAGS
+config.omk-default
+cscope.*
+*~
diff --git a/src/fwp/README b/src/fwp/README
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/src/fwp/fwp/.gitignore b/src/fwp/fwp/.gitignore
new file mode 100644 (file)
index 0000000..110f125
--- /dev/null
@@ -0,0 +1,6 @@
+_build
+_compiled
+TAGS
+config.omk-default
+cscope.*
+*~
diff --git a/src/fwp/fwp/Changelog b/src/fwp/fwp/Changelog
new file mode 100644 (file)
index 0000000..c6997b4
--- /dev/null
@@ -0,0 +1,1709 @@
+commit eb429599f8240a4a141aa02ba76066b96df5341c
+Merge: 8832dd6... 613a4c5...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Mar 21 10:02:55 2008 +0100
+
+    Merge branch 'martin'
+
+commit 613a4c543c5a7c8cace599583f373bc66afbea80
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Mar 20 19:37:51 2008 +0100
+
+    Added agent and contract table locking
+
+commit c4c3ec3c573e07602681f3e2a192ea1343c10619
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Mar 20 19:01:43 2008 +0100
+
+    Added global agent_table variable and hence  changed  parameters of fwp_agent_atble functions
+
+commit 9c33faf6efe3b0c2de915ae2081a8d885726197c
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Mar 19 16:56:18 2008 +0100
+
+    Bug fixes
+
+commit 28c971e13430da37c08d8ea68982c798fde70e5a
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Mar 18 18:57:18 2008 +0100
+
+    Unulutizing fwp lib :-)
+
+commit 23cbe546255e63c5fc84e5d8a4c95c533c6112d8
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Mar 17 10:46:13 2008 +0100
+
+    Added fwp.h - library header file for user
+
+commit 3c0176151058c5869817972a5dd904a3c7d84bc2
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Mar 17 10:32:52 2008 +0100
+
+    fwp_proto moved to fwp_comm
+
+commit dff772bb588e0c7bf4d421f3436e7f3961eac9b9
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Mar 17 10:18:03 2008 +0100
+
+    Compilation fixes
+
+commit 3ce13aadcdd99d92c68237b0a45216e858234298
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Sun Mar 16 23:47:35 2008 +0100
+
+    the type changes of fwp vres and endpoint
+
+commit a90be451e06c736a243a38ee94ab9fa039b9b07d
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Mar 14 18:06:01 2008 +0100
+
+    Added fwp_types.h - defiens user types
+
+commit 6e644d1d9444cd9159c3c3babe797b950f18a4cd
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Mar 14 18:04:10 2008 +0100
+
+    WIP:Ulutizing fwp_vres and fwp_endpoint
+
+commit 6b6a258fc7e7a373992e54fa8da98cc70f20d811
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Mar 13 14:52:17 2008 +0100
+
+    Added appcall_id to msg header, fwp agent got simplified, removed forwarding table
+
+commit 3573e776ed210793d336de4f7922391957458a15
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Mar 11 17:47:06 2008 +0100
+
+    Compilation fixes
+
+commit 2c2b1a1764363bf7bd61ccc71ed69d3b9e9dc720
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Mar 10 12:42:30 2008 +0100
+
+    label changed to id
+
+commit 426fbdfc2dc2977025a399fcbd74ad201278cc39
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Mon Mar 10 01:52:38 2008 +0100
+
+    fwp_agent_table operations added
+
+commit 220aeda53a794fb6cce5f1d153b90c0634c022c3
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Mar 6 18:22:26 2008 +0100
+
+    Added aegnt table
+
+commit 6adbfaff1489729164ef224e14ce4f1dbd5e9d0c
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Wed Mar 5 01:05:53 2008 +0100
+
+    Stupid admctrl test integrated
+
+commit cf454896a3519da74f583b0aa40d7846ef9f8a84
+Merge: 34eb301... ed92819...
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Tue Mar 4 20:51:33 2008 +0100
+
+    Merge conflict resolved
+
+commit ed92819bae022eaa4a698051a017ca7076648996
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Mar 4 18:07:01 2008 +0100
+
+    ulutize fwp_contractbl
+
+commit 34eb301c01db63ecddbc13c49c32e3a8248a728b
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Mon Mar 3 01:05:40 2008 +0100
+
+    Revert "tial to ulutize contractbl"
+    
+    This reverts commit 99685a757ddc777074888a0ef72890a70c4fe168.
+
+commit 99685a757ddc777074888a0ef72890a70c4fe168
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Mon Mar 3 01:00:25 2008 +0100
+
+    tial to ulutize contractbl
+
+commit b9332abfaa147ba287bd90ff928e4f8b50d9cd90
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 29 11:12:33 2008 +0100
+
+    AdeUlut lib
+
+commit 9319620cba583f8a5e0d4eb3a6976f588f539008
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Feb 28 16:02:34 2008 +0100
+
+    Copy data passed in argument in fwp_send to msgb.
+
+commit fb4ea826583ce09aa5f73ab584ef70556e5e4092
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Feb 28 15:58:46 2008 +0100
+
+    Revert "Bug fixes in fwp_vres, budget mechanism modified. For testing purposes and easy testing , budget counts number of messages not bytes."
+    
+    This reverts commit c9dea3dc90ebedd8e93ffce4f1deade4e6c01416.
+
+commit c9dea3dc90ebedd8e93ffce4f1deade4e6c01416
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Feb 28 15:55:38 2008 +0100
+
+    Bug fixes in fwp_vres, budget mechanism modified. For testing purposes and easy testing , budget counts number of messages not bytes.
+
+commit 02cf867e6bd0b33180801180bbae73692beaa4b7
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Feb 28 15:54:36 2008 +0100
+
+    Bug fixes in fwp_vres, budget mechanism modified. For testing purposes and easy testing , budget counts number of messages not bytes.
+
+commit 8832dd611f5b2d01dd4ba3e65818a53e40ef5240
+Merge: 882fd8b... 3dbad8f...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Feb 27 18:21:08 2008 +0100
+
+    Merge branch 'martin'
+
+commit 3dbad8fd7c890c8a3ef201955c3fe81d63b27987
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 22 17:47:19 2008 +0100
+
+    fwp_ac files removed
+
+commit 4d3dafd09fa8278741916a776b8ac9833f2f7371
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 22 17:36:46 2008 +0100
+
+    Each vres now open socket for its communication
+
+commit 882fd8bd3df19b2c19086d33d59519a8e7028e2c
+Merge: 7e3fa40... e0f2900...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 22 13:00:55 2008 +0100
+
+    Merge branch 'martin'
+
+commit e0f2900a35a67e485e288905999b408d83700467
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Feb 21 18:02:07 2008 +0100
+
+    Added fwp_vrestest2
+
+commit d671ec50b6290986210004124ca2c03a0ee68b87
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Feb 20 18:55:14 2008 +0100
+
+    fwp_contratbl files moved to mngt directory
+
+commit 9dcd2689a0b1919b85a62fd8d269c0d9caf38b82
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Feb 20 18:49:59 2008 +0100
+
+    Added packet budgeting into vres_tx_thread
+
+commit 963aaf42afb8a8c0751aa2cee1e14850e5c1281f
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Feb 20 18:07:25 2008 +0100
+
+    Fix in vres_tx_thread- setting period
+
+commit 2b5c5df2a045fecaa1df13af7b588e4abf7f3f9f
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Feb 20 11:31:53 2008 +0100
+
+    fwp_vrestest added
+
+commit 845a08e21fe2885f3536a794870427785cc1e05f
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Feb 20 11:30:44 2008 +0100
+
+    Bug fix v fwp_msgq and fwp_forwardtbl
+
+commit fed0db23892d79c56fdd8c327b029dce1a0e9f36
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Feb 19 18:32:43 2008 +0100
+
+    fixes in fwp_contract
+
+commit 84937f8e440662646d0da6f08af2d7fb637d07cc
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Feb 19 15:49:02 2008 +0100
+
+    Adding fwpagent forwarding table
+
+commit ef20a323f5cfc8b133b9cb91fbe6c913a5bb7989
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Tue Feb 19 02:27:22 2008 +0100
+
+    Fixes in fwp_contract - small msgb for both response
+
+commit 03261e2e2f0913c866b1ddafeb636ad67b847c7d
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Tue Feb 19 00:41:49 2008 +0100
+
+    Fix - id return in hashtbl_insert function
+
+commit 13b2a170cc812c7600a0aee3326ee0825d15a7a2
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Feb 18 18:51:21 2008 +0100
+
+    Fixes in fwp_agent and manager
+
+commit 36d731dde7bbfcf231fcf666ddee78758793df51
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Mon Feb 18 01:57:50 2008 +0100
+
+    Many fixes
+
+commit 425ccaf7d0a20ff2ff7ffea7c5902422e423cdd0
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Sun Feb 17 00:26:49 2008 +0100
+
+    Change the names of diectories
+
+commit 2a35d84ef68f7da58839c306ee4e8bdcb1531cb8
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Sat Feb 16 23:44:38 2008 +0100
+
+    Agent and manager compilation fixes
+
+commit a3e80a9fbfd279376fafdc0bb4b62fbb84d9c3d9
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 15 17:44:44 2008 +0100
+
+    fwp manager compilation fixes
+
+commit 7ad25090c253f7c22bb654c809c97f15ef38c464
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 15 14:18:36 2008 +0100
+
+    Move files from include and src directory up to libfwp directory
+
+commit d9418c4ba4f3d16c059a934eb0e5753a1a68e6ee
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 15 13:58:41 2008 +0100
+
+    Remove Makefiles in libfwp
+
+commit 0ab19307c1d11129fe3ab7f6c27c2a5f3fe47d16
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 15 13:42:03 2008 +0100
+
+    Added macros _fwp_sendto and _fwp_recfrom for sendto and recvfrom operations
+
+commit d0b4393035178dbae68803f26d93c3856d176bcb
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 15 10:58:45 2008 +0100
+
+    libfwp test fixes
+
+commit bc4f901dccf1a6322f953c3a317e7179a2d6f9a7
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 15 10:19:29 2008 +0100
+
+    rewrite of fwp_agent, adding hastable
+
+commit da3c99ae22798b0f15ede9c56851de54941087e3
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 15 10:17:43 2008 +0100
+
+    rewrite of fwp_agent, adding hastable
+
+commit e5a554ef37398301938a1578ac906f2158a0d752
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Fri Feb 15 00:46:18 2008 +0100
+
+    libfwp compilation fixes
+
+commit 5e776bad6039872b9340397c657b82fc8c3ce949
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Thu Feb 14 01:46:20 2008 +0100
+
+    compilation fixes
+
+commit 5775fb01027e4f592dda5670c73f53324c46324d
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Feb 13 19:19:02 2008 +0100
+
+    introduced fwp_vres_param, fwp_contarct_data
+
+commit eafcfca169c8660c481df26061f4cbf689999ee9
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Feb 13 12:34:22 2008 +0100
+
+    Split fwpmngr.c and change the name of directory - fwpme - FWP management entity is more comprehensive
+
+commit 1eb9d76645363dc9f829f090b502ee4e8f2886de
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Wed Feb 13 02:08:34 2008 +0100
+
+    fwp_msgb preparation change in mngr_input
+
+commit 8af62955be82793cd3b03e0d190aed11b4e39afa
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Feb 12 17:29:45 2008 +0100
+
+    compilation fixes
+
+commit a8f25f193413bea3efa18fce31183ed5f1fb57ee
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Feb 12 17:03:15 2008 +0100
+
+    Rename ctable->cntable and fwp_contract->fwp_cnt
+
+commit 72046daf10bf711c26ce9c942940d991c72b15ce
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Feb 12 16:53:38 2008 +0100
+
+    Contract table and operations modification
+
+commit 8e12cde82c64eeb4c4fcda49a1de1c03f2902485
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Feb 12 12:49:40 2008 +0100
+
+    Split internal and external representation of contract
+
+commit 7e3fa409ef9a38f2670ceee7934a28f4514a3c5b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Feb 11 23:01:06 2008 +0100
+
+    Fixes and additions to more_sta scripts.
+
+commit 6f388988288240bd8616828a610759f33629524c
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Feb 11 21:23:50 2008 +0100
+
+    Fixed bug in generated data files.
+
+commit a31cbabea4aad0185aef25b0c5452bb0e815f544
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Feb 11 19:33:01 2008 +0100
+
+    Updated version of more_sta scripts
+
+commit ffb0bd9b599d51a2055d653d72f047236960cb7d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Feb 11 17:08:58 2008 +0100
+
+    Added scripts for testing transmission from multiple stations.
+
+commit 369e41d7661e3108937524ac9a745028c72a816c
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Feb 11 17:06:32 2008 +0100
+
+    Removed debug message
+
+commit 152fb71def8200cc17458b69c2c8aacc2fc129d3
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Feb 11 16:18:54 2008 +0100
+
+    remove flag parameter from fwp ops
+
+commit a89ce5bc10439738b42baf7720caab5eb64ad2b4
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Feb 11 15:30:53 2008 +0100
+
+    fwp_prototets changed to use fwp_endpoints. Test passed.
+
+commit de7c277401b28242ccbd200c1eb0fde212e7d250
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Feb 11 14:56:39 2008 +0100
+
+    Delete all -o flags from title of graph.
+
+commit b3b5c14731224e1feb2c800687e8bb94479b2869
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Mon Feb 11 01:33:51 2008 +0100
+
+    fwp_endpoint compilation fixes
+
+commit e32e95266e3e524ea196e474794972521478929b
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Feb 8 18:01:56 2008 +0100
+
+    function parameter changes in fw_endpoint
+
+commit 139d5bf13c90ed36c2ed4abdb7626213f89d18ed
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Feb 8 09:17:02 2008 +0100
+
+    Use thicker lines for plotting individual directions.
+
+commit dbe943ee97c24508061b2cb627ee131c3d65ee6d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Feb 8 09:12:41 2008 +0100
+
+    Allow wclient and wserver to send packets with a specified interface.
+    
+    In combination with send-to-self patch (http://www.ssi.bg/~ja/#loop),
+    this allows to have both wserver and wclient running in one machine
+    and use multiple interfaces for communication.
+
+commit a193db919f72628f083c2e7eb85f179ef79fd975
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Fri Feb 8 00:31:54 2008 +0100
+
+    revert the last change
+
+commit a06668722dd2066438fb9b7ed7cbe7376f84f73f
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Feb 7 18:03:02 2008 +0100
+
+    change *epoint to epoint_id in endpoint calls
+
+commit b4626165880f3d599a29a477c19d0e3bc006b8aa
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Feb 7 16:09:54 2008 +0100
+
+    Added comments to fwp_endpoint
+
+commit 93ab2d4f22eebc1004b85142461e750f7626b395
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Feb 7 15:27:47 2008 +0100
+
+    Added endpoint bind and unbind ops
+
+commit 6f1d00c47c1d6ba3c48dad8671d88496594371a2
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Feb 7 07:16:19 2008 +0100
+
+    Opacity set to 1 in svg files. It is still slow :-)
+
+commit d53ce455f07f82e2030bdcc7334a4fdeb3613778
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Feb 6 17:59:29 2008 +0100
+
+    fwp_socket - addr field predefined to array of chars
+
+commit 9eb6d9a01881505672925890bbbfe42c6a5ec5a2
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Feb 6 16:48:04 2008 +0100
+
+    schedlat.c added
+
+commit b5f491e40a169d1c659b3c891cadcf9f02fdbfe4
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Feb 6 16:46:05 2008 +0100
+
+    Added test for measuring of CPU scheduler latency.
+    
+    I get strange results when measurements are run on my old laptop. This
+    application should help to determine, whether it is caused by the
+    laptop or something else.
+
+commit b73955ffa0c4b870a85c23df9e5afc7cdd845b6b
+Merge: ee842f8... 92d4606...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Feb 6 16:40:29 2008 +0100
+
+    Merge branch 'master' of rtime:/var/git/frescor
+
+commit ee842f8785c99fb7454be36373b2e30f5ffed15f
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Feb 6 16:39:33 2008 +0100
+
+    Final version of presentation for CAK colloquium
+
+commit 72b6e6d45b453ed509dcda8fa2383ce5450591be
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Feb 6 15:30:26 2008 +0100
+
+    Adding pointer to fwp_socket into fwp_endpoint
+
+commit 92d46060d0eb93af77c84bb78ce179641306c3d1
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Feb 5 19:14:58 2008 +0100
+
+    Adding martin branch
+
+commit 9f8a97ea1437b0b654c1bf2e071cab46540e071d
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Feb 5 16:08:03 2008 +0100
+
+    Little compilation fixes
+
+commit c78cffec714b7ab9e87fea336bb4a2c56007f28c
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Feb 5 16:01:13 2008 +0100
+
+    Created branch martin
+
+commit 561c2fe93efbc04c872309ffaa396127c81fc99a
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Feb 4 22:42:48 2008 +0100
+
+    First version of kolokvium presentation.
+
+commit e382bab54b1bea6ca1b34eda1f5f1635f0ea30dc
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Feb 4 17:33:23 2008 +0100
+
+    Modification of figures of Paris presentation-  adding svg files
+
+commit c0495cc1cfc20ea19396d7d3fef7786317885632
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Feb 4 16:28:04 2008 +0100
+
+    Modification of figures of Paris presentation
+
+commit 2584cf4a3582f50daa474e3ffbc702f4a6ca50bf
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Feb 4 13:25:42 2008 +0100
+
+    Paris presentation modified
+
+commit 58e07664e0814cfe8a686c2443a0e3579b0f6371
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Feb 1 18:17:26 2008 +0100
+
+    Admission test now calulates even PHY overhead for all possible PHYs.
+
+commit f5449bdbbb9a0ca69a6672ecd0bbdc3c5c7f6c80
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 30 10:53:45 2008 +0100
+
+    Modified plot of admtest comparion graph to produce PDF and have better readability.
+
+commit 2ed31eea5c2cd71e9427c6faf379ffc14d841497
+Merge: 1917640... d251106...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 30 01:48:22 2008 +0100
+
+    Merge branch 'master' of rtime:/var/git/frescor
+
+commit 191764098f6f11698ebe989fdff0cf3a2d8f0fa6
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 30 01:48:01 2008 +0100
+
+    Prezentation updated and added my slides.
+
+commit d251106d173050dc6690faacbfb6aa47f59e6012
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Wed Jan 30 01:21:02 2008 +0100
+
+    Add type fwp_vres_id_t
+
+commit 410d2ed7520c890b679faf1b46e8ed06260f533d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 30 00:44:51 2008 +0100
+
+    Added todo to utilization test
+
+commit 85d433e528863a492d8e4d4d769895cb92dd9463
+Merge: 5643381... 8c19e50...
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Wed Jan 30 00:27:01 2008 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 5643381a3865388c7b70e344b888c3ad5e7ad1e8
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Wed Jan 30 00:26:42 2008 +0100
+
+    Fixes in fwp_endpoint, split fwp_endpoint_cretae to fwp_send_endpoint and fwp_recv_endpoint
+
+commit 8c19e50e30bd03c4b51e5d0e0870ae49d6688e92
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 29 23:44:38 2008 +0100
+
+    Added some FIXMEs
+
+commit 721afdb0b617011706bd3330519e6d744e670656
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 29 23:43:04 2008 +0100
+
+    Added utilization based admission test and a testing application.
+    
+    The testing application compares results of utilization test with real
+    measured values.
+
+commit c732867c6fd103ccb20bde85276c7e48d0afd3b2
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Jan 29 17:37:47 2008 +0100
+
+    Created presentation dir, added Paris 2008 fwp presentation
+
+commit 2b2c4692be07cf18f593ce1489c4171b5412a3e6
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 29 10:07:54 2008 +0100
+
+    Admission test moved to a separate file to easily switch between different ones.
+
+commit 298251fd1c5c0eb2350f985271e873cad57efc0b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 29 09:20:17 2008 +0100
+
+    Other wclient modifications for FWP. Still not finished.
+
+commit e6cf160db78c208c0d56d521a7275e149a041e49
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 29 09:18:57 2008 +0100
+
+    Added warnings where I think something is wrong. Modified some doxygen documentation.
+
+commit 14b4283078b4c9dc420e3f530b48cf7fd968b3d7
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 29 09:15:41 2008 +0100
+
+    Fixes for wclient with FWP.
+
+commit da50199be80279e10b9264c24292632fb8712e94
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 29 09:13:57 2008 +0100
+
+    Fixed (updated) Makefile.rules
+
+commit fabcc73bf811c74df5fa59dc09a2c3ba44b26023
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 29 07:26:03 2008 +0100
+
+    Start of wclient rewrite for FWP.
+
+commit 87b7abb3b4006756e2ba1a5811f2326e438e0d67
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Tue Jan 29 02:58:09 2008 +0100
+
+    fwp_endpoint modification
+
+commit bbaf09fd7ee8957056f98cf8390b672e4338d1fb
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Tue Jan 29 02:57:54 2008 +0100
+
+    fwp_endpoint modification
+
+commit b0c6ed65161ae751384436df53493febcaaead31
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 28 19:13:32 2008 +0100
+
+    Added fiel for fwp endpoint imlementation
+
+commit abde2bea695d78405c3f8e2a9ac5ce1d189ca1c9
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 28 15:59:46 2008 +0100
+
+    changed return value in fwp_contract_negotiate
+
+commit ded5e7809b62314b1e47f688cf31d78cce921680
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Jan 28 14:23:04 2008 +0100
+
+    Added wme_test to fwp compilation tree. Updated Makefile.rules.
+
+commit 87f1c881beb6b807948b9fd00b914e22d3c1ab15
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 28 12:26:48 2008 +0100
+
+    Added temporal flag socketshare to fwp_msgb, to indicate whether  socket is shared, if not it is destroyed when msgb is sent
+
+commit f163c1f440033e9adbf3d45a22a0f1e52ad54ba4
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 28 12:17:43 2008 +0100
+
+    Bugfix in fwp_negotiate_response
+
+commit 615c2afe5b6ff046143606d8d4a0dc93ad8cd6a5
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Mon Jan 28 02:25:18 2008 +0100
+
+    changing msgb addr storage, fixes in fwp_mngr
+
+commit 7e61f9351512d348ffcca5896a83235c85980fa7
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Sat Jan 26 14:37:05 2008 +0100
+
+    Put a little documentation into fwp_proto.c
+
+commit c2e46222aaa99f3650b4276e1570854d9dfc7a5a
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Jan 25 17:51:52 2008 +0100
+
+    Change of fwp contract states
+
+commit 47ab6350fa37229352720041aa80fb308ff7d736
+Merge: bdb670b... 1776768...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Jan 25 17:37:13 2008 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit bdb670b0b4fd969ebed7bbf0719f14f11c937ec1
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Jan 25 17:37:00 2008 +0100
+
+    tx_thread cancellation modified by using pthread_cancel call
+
+commit 177676889a9df1d3e2cb80b1f8bf64812bba9408
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 25 16:28:56 2008 +0100
+
+    Fixed bug in handling of default parameters introduced by ptevious commit.
+
+commit 021fe7b524d999d18065b679bfa3c658bbdc3a0a
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 25 11:26:41 2008 +0100
+
+    Fixed handling of some command line arguments witout respoect of their position.
+
+commit b3bcb0a97f0448514c6df7f523bc820648406f9e
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 25 10:11:24 2008 +0100
+
+    Tiny cleanups in sat-graph script.
+
+commit 657d07a81a682c35e4eaae77ac72adf46c01747a
+Merge: 78b4809... b4f2392...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 25 10:06:10 2008 +0100
+
+    Merge branch 'master' of rtime:/var/git/frescor
+
+commit 78b48097b0b2a84e9038c84a3594d71b36e77775
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 25 10:05:14 2008 +0100
+
+    plot script rewritten to Perl to allow more complicated handling a various types of plot. Added -b to plot delay in both directions.
+
+commit b4f23929099a44618374a686445dfaa0cfbafff1
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Fri Jan 25 01:57:28 2008 +0100
+
+    Added fwp_vres_tx_thread cancelation
+
+commit 5f2793ef0687380e07a915547737cd6404e5fa76
+Merge: 30ba3f8... 95d225a...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Jan 24 16:54:26 2008 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 30ba3f80199a246ffd17c1e20005d86f8a22e310
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Jan 24 16:54:12 2008 +0100
+
+    Fixes in fwp_manager: memcpy-size arg, msgb->tail setting etc., fwp_mngrtest passed
+
+commit 820397195a46087d5b6c21af6e07d468002c521b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Jan 24 15:44:46 2008 +0100
+
+    Timestamp for the server is gathered and processed, so we can measure separately the delay from the client to server and from server to client. NTP synchronized hosts are required for this.
+
+commit 95d225a3c0259b62104f45983a5ae81a70db3c9c
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Jan 24 11:01:48 2008 +0100
+
+    Modification of various test scripts.
+
+commit 0bd4073bbf6f9e583a971352fa3d612ffd71f219
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Jan 24 11:01:09 2008 +0100
+
+    Added bounds for y axis in plots.
+
+commit d93a66e5398fec5c0382eb047846c34a03d531e6
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Thu Jan 24 03:13:47 2008 +0100
+
+    Manager fixes
+
+commit c6e2559e2e530d6d8d0d9805bcdc84987c969363
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 23 21:00:01 2008 +0100
+
+    Fixes in fwp_mngr
+
+commit 3b34d018900af91305d8195a2d6fee8d25441b20
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 23 09:40:10 2008 +0100
+
+    Added additional test and plot scripts
+
+commit d8444594a9f1db485028dfd0ebd17518cf9b45e6
+Merge: 1d88eb4... 54ef6fd...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 23 09:04:42 2008 +0100
+
+    Merge branch 'master' of rtime:/var/git/frescor
+
+commit 1d88eb426fc5d3039a3ba61e59819c5239c9f3ca
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 23 09:04:32 2008 +0100
+
+    Without setting the queue size, the program behaves as before.
+
+commit 54ef6fd83261597b0c2c33b8e80b83b6d25ace53
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Wed Jan 23 01:01:27 2008 +0100
+
+    Compilation fixes, added fwp_mngrtest as fwp demo
+
+commit f57f27f2a1f0eb1ac84030d448a47775b353135a
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Wed Jan 23 01:00:56 2008 +0100
+
+    Compilation fixes, added fwp_mngrtest as fwp demo
+
+commit 7978d999985a6833af05c91377fbf74f0cf58ee6
+Merge: 8d5b05b... cd1c4c4...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Jan 22 19:23:57 2008 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 8d5b05bd03f8a020dc16139a285f587d37c29ec2
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Jan 22 19:23:46 2008 +0100
+
+    Changes in fwp_mgr
+
+commit cd1c4c4ed18bf41419bf4bbf201890a8c4cddfde
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 22 16:38:44 2008 +0100
+
+    Modified be_sat plot commands to produce better graph.
+
+commit 82a70df849cc3bb74bb92d14a472638e03538e84
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 22 15:50:59 2008 +0100
+
+    Added be_influence test scripts.
+
+commit 648565555bb3c46b8c86f6fd52b6cf95b0d0652a
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 22 15:49:29 2008 +0100
+
+    Fixed multipaged graph pdf generation.
+
+commit 9aad5f4c098ab13138b76ca2f832129d86b73736
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 22 14:57:09 2008 +0100
+
+    Added -Q option to specify socket queue size. Fixed generation of text
+    comments in saver_results. Fixed error in calc_stream_params.
+
+commit 30aee11958de312fb05a7cf95285dc2ce738a95c
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 22 14:55:32 2008 +0100
+
+    Plot script reworked to have test aligned.
+
+commit 28a45549fd886487afb9da279519e3464b5fd953
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Tue Jan 22 10:14:41 2008 +0100
+
+    The size of socket's send buffers set to zero to decrease queuing delay.
+
+commit 641847e53a4eed6d980df1dafb1316af60d51f78
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Jan 22 08:51:30 2008 +0100
+
+    Adding old wifi presentation to CAK Kolokvium directory
+
+commit e3d0ff5034614d938b569dbc625f64f38ecea935
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Tue Jan 22 02:33:17 2008 +0100
+
+    Changing the name of sockets in fwp_init
+
+commit 1938bf2e1ada703386a3cb179b59a05cc8832291
+Merge: bba7705... 56a8855...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 21 19:24:49 2008 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit bba7705e7d4180c31a60b0df417620328dec9d6a
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 21 19:24:22 2008 +0100
+
+    lots of changes in fwp_init and fwp_mngr
+
+commit 56a88554db16903044f9e210a358140636730f7b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Jan 21 16:02:25 2008 +0100
+
+    Added scripts for running and drawing saturation tests.
+
+commit ba7a613b8b01710e22825c645688c661a26824b5
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Jan 21 10:16:49 2008 +0100
+
+    Fixed bug in send_packet.
+
+commit 36b2bcd9bd92f617e54131b6b00b90ff49f05385
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Sun Jan 20 16:20:33 2008 +0100
+
+    Change in in fwp_msgb: addr is pointer to include unix/inet address and  head changed to buf_start.
+
+commit 8cab450b8463a847e8cad8d7ec6dfeb54adc9ef6
+Merge: d30337f... 9968b3c...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Sat Jan 19 21:49:04 2008 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit d30337fa06bc981ec48e3a894af02a299985b7c6
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Sat Jan 19 21:48:51 2008 +0100
+
+    Added mutex to msgq and vres_table
+
+commit 9968b3c5d6cb235b4b322ef5bc6ab8f700e9ed45
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Sat Jan 19 10:21:45 2008 +0100
+
+    wclient cleanup
+
+commit 1566570c841ffb70a2806092e70404e45e1db277
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Sat Jan 19 09:18:02 2008 +0100
+
+    Added PNG output
+
+commit fb303b5c000f3dd28ec5e7ebbcedeb30bc405724
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 19:23:56 2008 +0100
+
+    Compiled with -O2
+
+commit bd45080ba9cba0ab094e502d8bc8d1e37e1c698d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 19:20:33 2008 +0100
+
+    Removed unnecessary fields from msg strcuture.
+
+commit 4a5c81b698fcec3cd82a282bd91d1c767d6ab232
+Merge: 05ac88f... 451c865...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 19:01:11 2008 +0100
+
+    Merge branch 'master' of rtime:/var/git/frescor
+
+commit 05ac88ff71d53c07b2843b7428995e5dd03e7d12
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 19:01:03 2008 +0100
+
+    Satration measurements removed, added real bandwidth measurement.
+
+commit 451c8656a4ae57b8a930ffc093f21e919edcc307
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Jan 18 18:41:36 2008 +0100
+
+    fwp_sendrecvtest -done, fixes in fwp_vres, added fwp_set_rt_prio
+
+commit aa7593a4053a8b91f879972a330be633b7270a49
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 18:25:37 2008 +0100
+
+    Attempt to make saturation measurement more precise. Not very sucessfull.
+
+commit 18e2eee95f9895566f6e04a3e789b4ea7323daf5
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 18:12:40 2008 +0100
+
+    Unsucessfull attempt to measure send and sendback delays.
+
+commit 926acafc1a538a108226ae14e79b9a7c57887c72
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 17:52:52 2008 +0100
+
+    Added -o option to plot command. Renamed some variables.
+
+commit 9e98519ca8349baaee4a992a9a13992b60388b0a
+Merge: a71aa50... 0442299...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 17:51:51 2008 +0100
+
+    Merge branch 'master' of rtime:/var/git/frescor
+
+commit a71aa50df71d90adec9278ab949e99b5c565d43f
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 17:51:44 2008 +0100
+
+    Added a possibility to measure saturation bandwidth.
+
+commit 53e2e86b458d4f11c667e829a42835ac53e53eb0
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 14:05:05 2008 +0100
+
+    Fixed processing when resetting statistics.
+
+commit 0442299ab58cba8025476dbcf28488456aabc9f5
+Merge: a1c62ca... 4f522a5...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Jan 18 14:02:31 2008 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit a1c62ca3758d4d7c2b0ec1ee3880ae10cb345a0e
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Jan 18 14:02:14 2008 +0100
+
+    Added config.omk, lifwp fixes in fwp_ac and fwp_vres
+
+commit 4f522a5ec517be632bc2f9c3f1d7c030229bf006
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 13:07:28 2008 +0100
+
+    Added -q switch to reset statistics when some queue becomes full.
+
+commit 580c9d23c93d5c048e1288cee3a6e4ded248344b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 11:09:22 2008 +0100
+
+    It is possible to specify message size per stream.
+
+commit 04e37e3a061c0106a9ab8a5d60f6c4a3b1e704fa
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Jan 18 11:08:08 2008 +0100
+
+    Fixed handling of send when it would block.
+
+commit ba149a651aec9ed5efd3f11bf159e2f6622e8e7f
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Fri Jan 18 02:06:38 2008 +0100
+
+    fwp_vrestest dir changed to fwp_prototest and test renamed to fwp_sendrecvtest
+
+commit 77134012adff0d3ed3397d43974b38d97ac52570
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Jan 17 18:49:05 2008 +0100
+
+    Added fwp_vrestest-not completed
+
+commit 3267c081fe8f06bc911ba30316f9f8776794f098
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Jan 17 14:58:12 2008 +0100
+
+    Added test for unix-dgram
+
+commit 0b2755a541854004b9a7e662454f9f25a298e309
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Jan 17 11:10:45 2008 +0100
+
+    Added Makelfiles to fwp_msgtest and unixoscktest
+
+commit ae6c4b211196114b14bb4b48d42e8b9fb0ef641b
+Merge: af8b0a1... d1d8a1c...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 16 20:39:46 2008 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit af8b0a1b8a91409505dc09b64864547e309b29ff
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 16 20:39:33 2008 +0100
+
+    Added unixclient_thread - test for threaded unix communication
+
+commit d1d8a1c047180145536efb8231790bbd64f9f540
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 16 18:30:02 2008 +0100
+
+    Modified Makefile.rules to support compilation together with FRESCOR without the need of rewriting their Makefile.
+
+commit 3c0447fb21c5d9bf1f074cb9d601c0adece76f6f
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 16 17:48:01 2008 +0100
+
+    Sending socket changed to non-blocking mode.
+
+commit 2f17f10761a343a589af554c592148fbff93f80a
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 16 17:23:13 2008 +0100
+
+    In resulting graphs 100% represents the number of sent packets and if
+    there is packet loss, the graph don't reach 100%.
+
+commit 66908fd85d3645f519c828a095d62ea8b78f6986
+Merge: 280e4cf... b866360...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 16 16:57:14 2008 +0100
+
+    Merge branch 'master' of rtime:/var/git/frescor
+
+commit 280e4cf85e1694d81c6911e7cd59d07500e5e2f0
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 16 16:31:25 2008 +0100
+
+    Server adds timestamp to the packet
+
+commit b8663609a5c1bb89abe5cf2e147c471180d3343f
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 16 16:07:52 2008 +0100
+
+    Added tests/README and change msgtest to fwp_msgtest
+
+commit c882166fd30d32239ea3e870e265cac60b722974
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 16 15:41:05 2008 +0100
+
+    Unixsocktest-finished, hashtest(incomplete) moved to hastest directory
+
+commit 459509d31889b453397263a0cd767d259bf0f274
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 16 13:50:45 2008 +0100
+
+    Move unixserver-client to unixsocktest and msgqtest to msgtest
+
+commit 313b53c2623b354c08bcac8e77c232777a9e56a4
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 16 13:44:20 2008 +0100
+
+    Move unixserver-client to unixsocktest and msgqtest to msgtest
+
+commit bbaa3f12a581830b468da9b27ec3eae637b01ec0
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Wed Jan 16 00:56:39 2008 +0100
+
+    Added test for unix sockets - not finished
+
+commit 19079d3f7cd4b213e14f717aee6c428b4af6a26a
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Tue Jan 15 21:44:19 2008 +0100
+
+    Message queue test finished. Libfwp passed test
+
+commit cb570312f09c480a1387d1cfc907350d1bb329a8
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Jan 15 18:50:06 2008 +0100
+
+    Added msgq test-not finished.
+
+commit 6114525c64b8f6ad7407d7b65799e2d1246209fc
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Jan 15 11:21:53 2008 +0100
+
+    Fixed fwpmgr compilation error
+
+commit 4969cee3c000c6493ebbec2d03199b801a91fda9
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Tue Jan 15 00:51:43 2008 +0100
+
+    Few fwp mngr compilation error fixes.
+
+commit 2ebe0337296835fa132764e5d125462fce1a96f1
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 14 19:20:50 2008 +0100
+
+    Small modifications in fwp_mgr
+
+commit ab881f8f785885621b16212d3648853e275fff76
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 14 15:41:36 2008 +0100
+
+    change msgq pamars first->out, last->in
+
+commit 9bb0636d9c9fbd704c2bb9201e1045d9e92160ec
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Jan 14 11:27:18 2008 +0100
+
+    Fixed compilation problems.
+
+commit eaa6ea02ea246437d64309d4b0a48bc8d82844ac
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 14 01:56:23 2008 +0100
+
+    Changing the structure of fwp client,server threads
+
+commit dc492490138ab672aff0109573282eefbfff9c6d
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Sun Jan 13 18:14:22 2008 +0100
+
+    fwp_client modification - wake up when a new message comes
+
+commit bd0e02dfcb24efc5b54a36961c4aec48cead118e
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Sat Jan 12 09:51:32 2008 +0100
+
+    Change fwp_msgb.buf_start to fwp_msgb.head
+
+commit f5552fffd719887d6c69b6595bfe315bc481d80f
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Jan 11 22:18:10 2008 +0100
+
+    Zmena fwpman.c na fwpmgr, da se skompilovat beta verze manageru
+
+commit 87cf9882efe63448a4d16e2167b0c36d28b964df
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Jan 3 15:47:06 2008 +0100
+
+    Pridanie makefile suborov do fwp_manager adresare
+
+commit d29f7a39424579e7bdfe57295e9f59cfdf4e6132
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Jan 3 15:40:45 2008 +0100
+
+    Presun souborov fwp manageri
+
+commit 59d7929d584388dc67ac50f213bed15e3bd869c0
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Fri Jan 11 00:21:01 2008 +0100
+
+    Upravy vo funkci fwp klienta
+
+commit 23b512d743e741bbdec700599e6e52b969205861
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Jan 10 19:30:43 2008 +0100
+
+    Upravy ve funkci fwp servera
+
+commit 732dbd0495bc4bd1c44665cd1982cf1357073a3b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Jan 10 12:39:41 2008 +0100
+
+    Added warnings with notes to sources
+
+commit f380c205a8aec0047b0dd176e8abba7698eea97b
+Merge: 465235e... d48652c...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Jan 10 12:38:08 2008 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 465235ec144df44dd9fea824d73117e5e2006f9a
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Thu Jan 10 12:35:22 2008 +0100
+
+    Upravy fwp managera
+
+commit d48652ce0f402be208b2547350b687a9732736ed
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Jan 10 10:54:16 2008 +0100
+
+    Added forgotten Makefile
+
+commit 18ca0eb55aa1541829c45e38cf8a00ce9f131c7e
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Jan 10 10:53:30 2008 +0100
+
+    Added .gitignore files
+
+commit 0f8b9a0134465ab11f5bc10bcd9e18c124eac275
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Jan 10 10:37:51 2008 +0100
+
+    Now, the comments are better recognize by doxygen.
+
+commit b375ae428ab9bcdbbe233b44877ae0aef45b8ae3
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Jan 10 10:11:07 2008 +0100
+
+    Updated Makefile.rules and leaf Makefile from current OMK repository.
+
+commit fd9ba5584da1aceff8316ab3e4428c9e56cd0ed4
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Thu Jan 10 01:29:20 2008 +0100
+
+    drobne zmeny v fwp_manager
+
+commit 48ed412ddc7ec1c1d687970f5eb94fd0f7481f67
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Wed Jan 9 23:47:46 2008 +0100
+
+    pridanie fwp_init
+
+commit 80307c91d1a1a56a20ed2419e9e71887e57aa6a9
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 9 19:02:26 2008 +0100
+
+    pridani posilani negotita zparv pres unix socket v fwp_negotiate
+
+commit ff5ae217778862977d62502e024550d737a33e08
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 9 19:01:09 2008 +0100
+
+    pridani posilani negotita zparv pres unix socket v fwp_negotiate
+
+commit 923038f199ae78f5cf990e62fa5037aaef0b2414
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 9 18:26:32 2008 +0100
+
+    Pridana kompilacia fwp_ctable
+
+commit f1595d35ac434638472b7a6d9be88c9f379c5499
+Merge: 89be03e... 03502c9...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 9 17:07:27 2008 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 89be03e935cebb061ff7a23a72c5d3db2ecb7da8
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 9 17:06:25 2008 +0100
+
+    Prvni release fwp knihovny
+
+commit 03502c99e260682e7fe5c888f32b756a2ac2502b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Jan 9 15:01:40 2008 +0100
+
+    Added Doxygen config file
+
+commit c0deac52e54066e84c7420ab41873bb2eca4700c
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date:   Wed Jan 9 03:04:09 2008 +0100
+
+    pokracovani v oprave chyb
+
+commit c3904e20008f1e21f4311e5b85b50501ef184d8b
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Jan 8 20:04:53 2008 +0100
+
+    upravy pred kompilaciou
+
+commit 5ba550fea99ff4761df86588f5e31782a43c412c
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 7 17:58:51 2008 +0100
+
+    pridani fwp_ctable.h do libfwp
+
+commit 33ea7ac8f71e135ad69518818c36a2a4f6f88014
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 7 17:53:50 2008 +0100
+
+    nacrt fna_negotiate funkce
+
+commit d76de837c9abb9bbba21904fadcd21ca349b0552
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 7 11:16:57 2008 +0100
+
+    Pridani operaci pro praci s fwp_msgb
+
+commit 587496ad389d1cfa9db533dc1d304a14f6f2b2b2
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Jan 7 11:06:55 2008 +0100
+
+    zmena fwp_msg_entry na fwp_msgb, nastin seralizace v fwp_msg.c
+
+commit d93849e9a6b36e25d4a259b4354d61b993da1a85
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Wed Jan 2 13:54:37 2008 +0100
+
+    Added initial version of FWP.
+
+commit 86c0ce56c949eabe58769d980921662a0caeddb1
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Dec 7 18:46:53 2007 +0100
+
+    Fixed x axis label.
+
+commit 85c1c78df89d9a828976311ce2d557ef18b31f2b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Dec 7 17:58:30 2007 +0100
+
+    run can be now called from arbitrary directory
+
+commit 5b32b9b7935cb6e9594262dcd7bfc00aee3760e5
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Dec 7 17:18:55 2007 +0100
+
+    Bandidth of 0 can be specified without errors.
+
+commit 1122eda1fdd61fe1d195eb762d8f5222b8b815da
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Dec 7 16:54:16 2007 +0100
+
+    Added forgotten -P option to plot
+
+commit bb3d7841e932bdf4687f1f9e2ce6676c491fa148
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Dec 7 16:38:17 2007 +0100
+
+    Fit program output to 80 chars wide terminal
+
+commit 4e89a8160969ebdaa8a3632c1aca88261a6188f8
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Dec 7 16:37:25 2007 +0100
+
+    No fixed ranges in plot, so we can zoom in an interactive mode.
+
+commit 76f89b6aaf25f372401e2274064aa8c9367eccc8
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Dec 7 09:47:45 2007 +0100
+
+    Fixed y axis title
+
+commit 35a679663abb8e9fa5ef61e2b37ab027f34c828a
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Dec 7 09:34:09 2007 +0100
+
+    Execute tests in alphabetical order
+
+commit c3058b5cc12f312dd8374fbddaa94f177be41136
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Dec 7 09:32:34 2007 +0100
+
+    Added -B and -T options for default parameters of -b
+
+commit 2d8b44f8364aa9a9bb66b6553c4f7828c0132def
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Fri Dec 7 09:31:20 2007 +0100
+
+    Added pdf output to plot
+
+commit 9a8fed4cc0e88b79c4a471bb3f17ed610d68176d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Dec 6 19:30:01 2007 +0100
+
+    Test is easier to break by CTRL-C
+
+commit cfb607d380b3506ce7b8b3eb727683acd30664a6
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Dec 6 18:08:28 2007 +0100
+
+    Some plotting fixes
+
+commit 1032b8d8ce3ea1921991f4cbab856350e2d45708
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Dec 6 17:16:35 2007 +0100
+
+    Fixed stream statistics and their display in graph.
+
+commit 952f7c420dd0b081e0182630420f03563713143c
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Dec 6 17:08:25 2007 +0100
+
+    When plotting, a point is down only if the PDF function changes its value.
+
+commit 5e0107ce61c10ef1b11748dd5252d0bbaa0ac145
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Dec 6 16:19:39 2007 +0100
+
+    All statistics in plots (used enhanced mode).
+
+commit 7fb4427a5d83449e29e20e6802744c1320346e99
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Dec 6 15:22:24 2007 +0100
+
+    Small fixes of wclient terminal output.
+
+commit 19bae345036415cffbb7ac7f65dc51438c08c116
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Dec 6 14:21:33 2007 +0100
+
+    Added scripts for running multiple experiments in batch manner and plot their results.
+
+commit a82b6a1329cf8553af8287620db68fad40187f55
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Dec 6 13:10:38 2007 +0100
+
+    Fixed graph generation
+
+commit bec3d81eeae63551c617cdc6d20b887e2a303d21
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Dec 6 12:32:03 2007 +0100
+
+    Values equal to 100% are no longer displayed in graph
+
+commit 00b777320d2b22b68503d4c2a0eb868722cbf189
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Dec 5 17:44:16 2007 +0100
+
+    Graph is generated as delay probability distribution function.
+
+commit 5f356cf71c24069fa4064ef4da55cb4e3284fdd4
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Dec 5 15:45:51 2007 +0100
+
+    Added \n to help messages.
+
+commit 53ae4c68118e047f8eb1e6b3bca2737aed9d8169
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Dec 5 15:44:30 2007 +0100
+
+    Added -b (bandwidth) parameter
+
+commit 1290f28cb7c073bf2022ddcdabc099fefae82c47
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Wed Dec 5 10:19:03 2007 +0100
+
+    Added -g (granularity) option.
+
+commit c2a281d4bf28f7fb85bb529a887e15a3791481a0
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Dec 4 11:07:50 2007 +0100
+
+    Rozdelenie patchu na patch povoleni qos a nastavenie AC fornt(RALINK)
+
+commit 596cdd32cf0fa5071c7892c48b2267e472677892
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Dec 3 18:09:42 2007 +0100
+
+    Oprava chyby deleni nulou v save_results
+
+commit fb635eee995d15f1596ab8e493c7016e4095e409
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Dec 3 18:00:03 2007 +0100
+
+    MSEC nahrazen lepe za MSEC_TO_USEC
+
+commit 72cea358be6d3d48fcb29598d406f0958858e3db
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Dec 3 17:56:04 2007 +0100
+
+    Zmena AC_QUEUES->AC_NUM
+
+commit 5b69b656b5b034a85ccbf9c39f3e3c47a29504bb
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Dec 3 17:51:35 2007 +0100
+
+    SEC_TO_USEC,USEC_TO_NSEC, MSEC_TO_USEC makra pridany
+
+commit c0b69bb4a1937c584bea85edd6cf2ecde825881b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Sun Dec 2 13:12:27 2007 +0100
+
+    Fixed compitation of sender period
+
+commit 7788c3fcc024eb3bc93a126213259cfc0559d902
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Sun Dec 2 02:30:45 2007 +0100
+
+    Added -o and -c command line options. Output file contains information on how was wclient invoked.
+
+commit 551b27f149519503ada4bd673d6c88f35e027a48
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Sun Dec 2 00:41:09 2007 +0100
+
+    Added jitter option -j.
+
+commit bc68b35b3df7c9e8d11d6699bcab0a3d71a4f270
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Sat Dec 1 23:43:53 2007 +0100
+
+    gethostbyname() works. Can send differently sized packets
+
+commit 816c30994b4dba230bafbdd718762058cf5577b1
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Sat Dec 1 18:46:33 2007 +0100
+
+    Added runtime statistics (to check correctness of results).
+
+commit 6abeb141d4cd25f79e1aec58ed0f5be1bde934bd
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Sat Dec 1 17:25:27 2007 +0100
+
+    All time units are in microseconds.
+
+commit 7a2efcfd096dc83dc9f37d21cd9c3304a0cb1b74
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Sat Dec 1 12:46:01 2007 +0100
+
+    Task runs with RT priority, added run script, common code added to common.c.
+
+commit 8b46f7cb490978248533815f371eafe6b894713a
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Nov 30 14:12:56 2007 +0100
+
+    Kosmeticke upravy wclient.c, pridani DEBUG volby
+
+commit bf03e79fb4f7941247efa2880b5af768647ec99d
+Merge: 46af599... 9f21e1b...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Nov 30 14:05:22 2007 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 9f21e1b5f4d4ef526189344da161b1a3edc05b61
+Author: root <root@sum2.felk.cvut.cz>
+Date:   Fri Nov 30 14:00:42 2007 +0100
+
+    Pridana DEBUG podminka do wserver
+
+commit 46af5990453301bc8f9c31b60de49096226b3a6e
+Merge: dd18ec1... 6b4685d...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Nov 30 13:57:27 2007 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 6b4685da67a5613caee6ba408a7e3d9b1a696678
+Author: root <root@sum2.felk.cvut.cz>
+Date:   Fri Nov 30 12:53:18 2007 +0100
+
+    Kosmeticke uopravy wserver.c
+
+commit dd18ec13d7994ef4912d8294a50b4f9987e85c35
+Merge: e3450bb... c5caf7f...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Nov 30 10:07:09 2007 +0100
+
+    Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit e3450bb09da7c7c13e717829bb866bac20be3e89
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Fri Nov 30 10:06:56 2007 +0100
+
+    wclient+plot_commands unknown changes
+
+commit c5caf7f938f9ff3aa40b026ebca1d420fbcfcec8
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Nov 29 19:22:46 2007 +0100
+
+    Fixed bug, where sender sent packets only to port 5100
+
+commit abfc31684ab8da9683f458c7c42b0bf219325845
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Thu Nov 29 18:43:36 2007 +0100
+
+    Granularity changed, results are normalized to percents
+
+commit a805f57eea582b96a377118f1a8e78762f545d1c
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Tue Nov 27 17:07:57 2007 +0100
+
+    Modifikace souboru pro genrovani grafu: generovani .eps formatu
+
+commit 0f4e00eddd67d11e986e51597be6fa3e4f31be85
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Nov 26 21:10:40 2007 +0100
+
+    Inicializace struktury
+
+commit 01eb6b8fbd57f476a17bbabe92108dc9a09170c7
+Merge: 883d04e... f96a6e8...
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Nov 26 20:53:54 2007 +0100
+
+    oprava wclient
+
+commit 883d04eb8b6d1dec43180036e9a6a488aa42676b
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Nov 26 20:50:24 2007 +0100
+
+    oddeleni sendpointu
+
+commit f96a6e8291f2f74cacd057e4941d60f4184bdbed
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Nov 26 18:37:57 2007 +0100
+
+    Predelano zadavani streamu
+
+commit 3465f90cea0598384651a38fac916845caf7889e
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Nov 26 17:59:51 2007 +0100
+
+    wmm kernel patch added
+
+commit 54858f4dc989b6ba1c373c571d2ad661b6991ec5
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Nov 26 17:51:47 2007 +0100
+
+    Simplified Makefile
+
+commit b1b24842ef9610beef9e3a068a4b7f7d4b7f761a
+Author: Martin Molnar <molnar@sum.(none)>
+Date:   Mon Nov 26 17:48:35 2007 +0100
+
+    Initial commit
+
+commit c70fea54041ebf45a01baf1d639529de2174002d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date:   Mon Nov 26 16:17:46 2007 +0100
+
+    Initial commit - empty readme
diff --git a/src/fwp/fwp/INSTALL b/src/fwp/fwp/INSTALL
new file mode 100644 (file)
index 0000000..74369e4
--- /dev/null
@@ -0,0 +1,34 @@
+FWP is built from source files by OCERA Make-System (OMK) [10]. Prior building FWP, default
+configuration file must be generated by running
+
+       make default-config
+
+Then, build process is started by calling
+
+          make
+
+in the top-level source directory. If the compilation is successful, the built targets are 
+placed under compiled directory. To create documentation from comments in source files run 
+doxygen from the top-level source directory. The generated documentation files are placed in the
+compiled/doc directory.
+The subdirectories of FWP main directory are:
+• libfwp contains sources of FWP library. The compiled library is called libfwp.a and is
+  placed in compiled/lib/libfwp.a.
+• fwp mngr contains sources of FWP agent and manager. The built application is called
+  fwpmngr resp. fwpagent and is placed in compiled/bin/fwpmngr and compiled/bin/fwpagent respectively.
+• tests contains sources of test programs. The built tests are placed in the compiled/bin-tests
+  directory.
+
+In order for application to use FWP, in must be linked to libfwp.a library. Further, FWP
+agent must be launched in every node. FWP agent can be started from command line by:
+
+        fwpagent -a 192.168.1.1
+
+where  -a specifies IP address of the
+manger. 
+There is only one instace of fwp manager running on access point machine and started by command
+       fwpmngr
+
+The contents of tests directory is often changing. The actual detailed list of test programs
+with their descriptions can be found in README file included in the directory.
+
diff --git a/src/fwp/fwp/Makefile b/src/fwp/fwp/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/Makefile.omk b/src/fwp/fwp/Makefile.omk
new file mode 100644 (file)
index 0000000..b51c919
--- /dev/null
@@ -0,0 +1,6 @@
+default_CONFIG = CONFIG_FWP=y
+
+ifeq ($(CONFIG_FWP),y)
+SUBDIRS = lib mngr wme_test tests
+CFLAGS+= -Wall -Wextra -D_REENTRANT
+endif
diff --git a/src/fwp/fwp/README b/src/fwp/fwp/README
new file mode 100644 (file)
index 0000000..ca61788
--- /dev/null
@@ -0,0 +1,32 @@
+Software description
+=====================
+Name:
+       FRESCOR WLAN Protocol (FWP)
+Version:       
+       0.1
+Status:
+       Alpha
+Authors:
+       Martin Molnar,
+       Michal Sojka
+Licence:
+       GPL
+       
+Brief description:
+       The protocol that applies FRESCOR to 802.11 networks
+
+Bugs:
+
+Description:
+       FRESCOR WLAN protocol (FWP) is a set of software components enabling FRSH applications
+       to communicate over IEEE 802.11 WLANs. It is designed to work on hardware conforming
+       to WMM specification and employs EDCA medium access mechanism. EDCA extends legacy DCF
+       function by prioritized medium access so that the packets in higher priority queue have
+       a higher probability to access the medium first. 
+       
+       FWP includes centralized admission control mechanism, which is conceptually very similar
+       to IEEE 802.11e HCCA admission control. 
+       FRESCOR applications negotiate network contracts that are analogous to TSPECs but 
+       unlike IEEE 802.11e admission control,where IEEE 802.11 management services are used, 
+       FWP uses FNA services [8] to manage the negotiation process.
+
diff --git a/src/fwp/fwp/fwp-demo1 b/src/fwp/fwp/fwp-demo1
new file mode 100755 (executable)
index 0000000..32a40bb
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+KONSOLE=${KONSOLE:-"konsole --profile bigfont"}
+TARGET=${TARGET:-192.168.1.100}
+#TARGET=localhost
+
+sudo iwconfig wlan0 rate 1M
+
+#export FWP_MNGR_ADDR=192.168.1.100
+
+$KONSOLE --geometry +0+0 --vt_sz 80x13 --noclose -e bash -c "_compiled/bin/fwpmngr" &
+BGM=$!
+
+sleep 1
+echo "Press a key..."
+read
+
+$KONSOLE --geometry +0+430 --vt_sz 80x2 -e bash -c "sudo fwptester $TARGET; sleep 10"&
+BG0=$!
+
+echo "Press a key..."
+read
+
+$KONSOLE --geometry +0+550 --vt_sz 80x2 -e bash -c "sudo fwptester -B 1000 $TARGET; sleep 10" &
+
+echo "Press a key..."
+read
+
+(
+    RANDOM=5
+    while true; do
+        $KONSOLE --geometry +0+550 --vt_sz 80x3 -e bash -c "sudo fwptester -c 30 -B $((RANDOM%200)) -s $((RANDOM%1300+40)) $TARGET; echo Finished; sleep 10"
+       sleep 10
+    done
+
+) &
+
+BG1=$!
+
+(
+    RANDOM=3
+    while true; do
+        $KONSOLE --geometry +0+700 --vt_sz 80x3 -e bash -c "sudo fwptester -c 20 -b VO:$((RANDOM%100)),VO:$((RANDOM%100)) -s $((RANDOM%1300+40)) $TARGET; echo Finished; sleep 10"
+       sleep 10
+    done
+
+) &
+BG2=$!
+
+echo "Press a key to finish demo..."
+read
+
+kill $BGM $BG0 $BG1 $BG2 
diff --git a/src/fwp/fwp/lib/Makefile b/src/fwp/fwp/lib/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/lib/Makefile.omk b/src/fwp/fwp/lib/Makefile.omk
new file mode 100644 (file)
index 0000000..6e538c9
--- /dev/null
@@ -0,0 +1,2 @@
+CFLAGS += -Wall -D_REENTRANT -g -D_FWP_INTERNALS_
+SUBDIRS= fwp frsh_fwp 
diff --git a/src/fwp/fwp/lib/frsh_fwp/Makefile b/src/fwp/fwp/lib/frsh_fwp/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/lib/frsh_fwp/Makefile.omk b/src/fwp/fwp/lib/frsh_fwp/Makefile.omk
new file mode 100644 (file)
index 0000000..c59ef13
--- /dev/null
@@ -0,0 +1,7 @@
+shared_LIBRARIES = frsh_fwp
+CFLAGS += -D_FWP_INTERNALS_
+frsh_fwp_SOURCES += fwp_fna.c fwp_fra.c fwp_block.c
+include_HEADERS= fwp_res.h fwp_fna.h 
+frsh_fwp_CLIENT_IDL += fwp_idl.idl
+include_GEN_HEADERS= fwp_idl.h
+lib_LOADLIBES+= fna fra 
diff --git a/src/fwp/fwp/lib/frsh_fwp/fwp_block.c b/src/fwp/fwp/lib/frsh_fwp/fwp_block.c
new file mode 100644 (file)
index 0000000..44ba0fe
--- /dev/null
@@ -0,0 +1,74 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#include <fwp_res.h>
+#include <fres_container.h>
+
+static const struct fres_block_desc fwp_sched_block_desc = {
+       .size = sizeof(fres_block_fwp_sched),
+       .serialize = (fres_block_serialize_fnc_t*)fres_block_fwp_sched_serialize,
+       .deserialize = (fres_block_deserialize_fnc_t*)fres_block_fwp_sched_deserialize,
+       .duplicate = fres_block_duplicate_default
+};
+
+static const struct fres_block_desc fwp_block_desc = {
+       .size = sizeof(fres_block_fwp),
+       .serialize = (fres_block_serialize_fnc_t*)fres_block_fwp_serialize,
+       .deserialize = (fres_block_deserialize_fnc_t*)fres_block_fwp_deserialize,
+       .duplicate = fres_block_duplicate_default
+};
+
+int fres_block_register_fwp()
+{
+       int ret;
+       ret = fres_block_register(FRES_BLOCK_FWP_SCHED,
+                                 &fwp_sched_block_desc);
+       if (ret)
+               return ret;
+       ret = fres_block_register(FRES_BLOCK_FWP,
+                                 &fwp_block_desc);
+       return ret;
+}
+
diff --git a/src/fwp/fwp/lib/frsh_fwp/fwp_fna.c b/src/fwp/fwp/lib/frsh_fwp/fwp_fna.c
new file mode 100644 (file)
index 0000000..a51e558
--- /dev/null
@@ -0,0 +1,260 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#include <fna.h>
+#include <fres_vres.h>
+#include <frsh_forb.h>
+#include "fwp_endpoint.h"
+#include "fwp_vres.h"
+#include "fwp.h"
+#include "fwp_res.h"
+#include "fwp_utils.h"
+#include "fwp_debug.h"
+
+int fwp_fna_init(const frsh_resource_id_t resource_id)
+{
+       int rv;
+
+       if ((rv = fwp_init()))
+               return rv;
+
+       return fra_fwp_init();
+}
+
+int fwp_fna_network_budget_to_bytes(const frsh_resource_id_t resource_id,
+                       const frsh_rel_time_t *budget, size_t *nbytes)
+{
+       *nbytes = budget->tv_nsec;
+       return 0;       
+}
+
+int fwp_fna_network_bytes_to_budget(const frsh_resource_id_t resource_id,
+                       const size_t nbytes, frsh_rel_time_t *budget)
+{
+       budget->tv_nsec = nbytes;
+       budget->tv_sec = 0;
+       return 0;
+}
+
+int fwp_fna_send_endpoint_created(fna_endpoint_data_t  *endpoint)
+{
+       unsigned int node, port;
+       fwp_endpoint_attr_t *attr;
+       struct fwp_endpoint *fwp_epoint;
+       int rv;
+       frsh_send_endpoint_protocol_info_t *spi;
+       
+       node = (unsigned int) endpoint->destination;
+       port = (unsigned int) endpoint->stream_id;
+       attr = NULL;
+       
+       spi = &endpoint->endpoint_protocol_info.send;
+       if (spi->size == sizeof(fwp_endpoint_attr_t))
+               attr = (fwp_endpoint_attr_t*)spi->body; 
+       rv = fwp_send_endpoint_create(node, port, attr, &fwp_epoint);
+       endpoint->protocol_info.body = fwp_epoint;
+       return rv;
+}
+
+int fwp_fna_receive_endpoint_created(fna_endpoint_data_t  *endpoint)
+{
+       unsigned int node,port;
+       fwp_endpoint_attr_t *attr;
+       struct fwp_endpoint *fwp_epoint;
+       int rv;
+
+       node = (unsigned int) endpoint->destination;
+       port = (unsigned int) endpoint->stream_id;
+       attr = (fwp_endpoint_attr_t*) endpoint->protocol_info.body; 
+       rv = fwp_receive_endpoint_create(port, attr, &fwp_epoint);
+       if (rv)
+               return rv;
+       
+       endpoint->protocol_info.body = fwp_epoint;
+       fwp_endpoint_get_params(fwp_epoint, &node, &port, attr);
+       endpoint->stream_id = port;
+       FWP_DEBUG("PORT= %d\n", port);
+
+       return 0;
+}
+
+int fwp_fna_send_endpoint_bind(fna_endpoint_data_t *endpoint, fna_vres_id_t vres)
+{
+       return fwp_send_endpoint_bind(endpoint->protocol_info.body, 
+                                       (struct fwp_vres *) vres->priv);
+}
+
+int fwp_fna_send_endpoint_unbind(fna_endpoint_data_t *endpoint)
+{
+       return fwp_send_endpoint_unbind(endpoint->protocol_info.body);
+}
+
+int fwp_fna_endpoint_destroy(fna_endpoint_data_t  *endpoint)
+{      
+       return fwp_endpoint_destroy(endpoint->endpoint_protocol_info.send.body);
+}
+
+/** FNA send routine */
+int fwp_fna_send_sync(const fna_endpoint_data_t *endpoint, const void *msg, 
+                       const size_t size)
+{
+       struct fwp_endpoint *fwp_epoint;
+
+       fwp_epoint = endpoint->protocol_info.body;
+       return fwp_send_sync(fwp_epoint, msg, size);
+}
+
+int fwp_fna_send_async(const fna_endpoint_data_t *endpoint,const void *msg,
+                  const size_t size)
+{
+       struct fwp_endpoint *fwp_epoint;
+
+       fwp_epoint = (struct fwp_endpoint*) endpoint->protocol_info.body;       
+       return fwp_send_async(fwp_epoint, msg, size);
+}
+
+/** FNA receive routines */
+int fwp_fna_receive(const fna_endpoint_data_t *endpoint,
+                       void *buffer, const size_t buffer_size,
+                       size_t *received_bytes, frsh_network_address_t *from)
+{
+       unsigned int from_addr;
+       ssize_t len;
+       struct fwp_endpoint *fwp_epoint;
+       int flags = 0;
+       
+       fwp_epoint = (struct fwp_endpoint*) endpoint->protocol_info.body;
+       len = fwp_recv(fwp_epoint, buffer, buffer_size, &from_addr, flags);
+       if (len < 0) 
+               return len;
+       
+       *received_bytes = len;
+       *from = from_addr;
+       
+       return 0;
+}
+
+int fwp_fna_receive_sync(const fna_endpoint_data_t *endpoint, void *buffer, 
+                        const size_t buffer_size, size_t *received_bytes, 
+                        frsh_network_address_t *from)
+{
+       unsigned int from_addr;
+       ssize_t len;
+       struct fwp_endpoint *fwp_epoint;
+       int flags = 0;
+       
+       fwp_epoint = (struct fwp_endpoint*) endpoint->protocol_info.body;
+       len = fwp_recv(fwp_epoint, buffer, buffer_size, &from_addr, flags);
+       if (len < 0) 
+               return len;
+
+       if (received_bytes)
+               *received_bytes = len;
+       if (from)
+               *from = from_addr;
+       
+       return 0;
+}
+
+int fwp_fna_receive_async(const fna_endpoint_data_t *endpoint, void *buffer, 
+                        const size_t buffer_size, size_t *received_bytes, 
+                        frsh_network_address_t *from)
+{
+       unsigned int from_addr;
+       ssize_t len;
+       struct fwp_endpoint *fwp_epoint;
+       int flags = 0;
+       
+       fwp_epoint = (struct fwp_endpoint*) endpoint->protocol_info.body;
+       len = fwp_recv(fwp_epoint, buffer, buffer_size, &from_addr, flags);
+       if (len < 0) 
+               return len;
+
+       if (received_bytes)
+               *received_bytes = len;
+       if (from)
+               *from = from_addr;
+       
+       return 0;
+}
+
+int fwp_fna_vres_destroy(const frsh_resource_id_t resource_id,
+                    const fna_vres_id_t vres)
+{
+//     return fwp_vres_close(vres);    
+       return 0;
+}
+
+fna_operations_t fwp_fna_operations = {
+    .fna_init = fwp_fna_init,
+    .fna_contract_negotiate = NULL,
+    .fna_contract_renegotiate_sync = NULL,
+    .fna_contract_renegotiate_async = NULL,
+    .fna_vres_get_renegotiation_status = NULL,
+    .fna_vres_destroy = fwp_fna_vres_destroy,
+    .fna_vres_get_contract = NULL,
+    .fna_vres_get_usage = NULL,
+    .fna_vres_get_remaining_budget = NULL,
+    .fna_vres_get_budget_and_period = NULL,
+    .fna_resource_get_capacity = NULL,
+    .fna_resource_get_total_weight = NULL,
+    .fna_vres_decrease_capacity = NULL,
+    .fna_send_sync = fwp_fna_send_sync,
+    .fna_send_async = fwp_fna_send_async,
+    .fna_receive_sync = fwp_fna_receive_sync,
+    .fna_receive_async = fwp_fna_receive_async,
+    .fna_send_endpoint_get_status = NULL,
+    .fna_endpoint_destroy = fwp_fna_endpoint_destroy,
+    .fna_send_endpoint_created = fwp_fna_send_endpoint_created,
+    .fna_send_endpoint_bind = fwp_fna_send_endpoint_bind,
+    .fna_send_endpoint_unbind = fwp_fna_send_endpoint_unbind,
+    .fna_receive_endpoint_created = fwp_fna_receive_endpoint_created,
+    .fna_receive_endpoint_get_status = NULL,
+    .fna_network_get_max_message_size = NULL,
+    .fna_network_bytes_to_budget = fwp_fna_network_bytes_to_budget,
+    .fna_network_budget_to_bytes = fwp_fna_network_budget_to_bytes,
+    .fna_network_get_min_eff_budget = NULL
+};
+
diff --git a/src/fwp/fwp/lib/frsh_fwp/fwp_fna.h b/src/fwp/fwp/lib/frsh_fwp/fwp_fna.h
new file mode 100644 (file)
index 0000000..aa51755
--- /dev/null
@@ -0,0 +1,53 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#ifndef _FWP_FNA_H
+#define _FWP_FNA_H
+
+#include "fwp.h"
+
+extern fna_operations_t fwp_fna_operations;
+
+#endif /* _FWP_FNA_H */
diff --git a/src/fwp/fwp/lib/frsh_fwp/fwp_fra.c b/src/fwp/fwp/lib/frsh_fwp/fwp_fra.c
new file mode 100644 (file)
index 0000000..0f5f1ac
--- /dev/null
@@ -0,0 +1,169 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <fra_generic.h>
+#include <fwp.h>
+//#include <fwp_fna.h>
+#include <frsh_distributed.h>
+#include "fwp_res.h"
+#include "fwp_idl.h"
+#include <stdio.h>
+#include <arpa/inet.h>
+
+
+UL_LOG_CUST(ulogd_fra_fwp);
+ul_log_domain_t ulogd_fra_fwp = {UL_LOGL_MSG, "fra_fwp"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fra_fwp_logreg_domains, ulogd_fra_fwp);
+
+static int create_vres(fres_vres_t *vres, void *priv)
+{
+       char id[40];
+       fres_block_basic *basic;
+       fres_block_fwp_sched *fwp_sched;
+       fres_block_fwp *fwp;
+       fwp_vres_params_t vparams = {0};
+       struct fwp_vres  *fwp_vres = NULL;
+       int rv;
+       size_t bytes;
+       char src[21] = "N/A";
+       
+       /* Prepare vres parameters */
+       basic = fres_contract_get_basic(vres->new);
+       fwp_sched = fres_contract_get_block(vres->new, FRES_BLOCK_FWP_SCHED);
+       if (!fwp_sched)
+               return FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT;
+
+       fwp = fres_contract_get_block(vres->new, FRES_BLOCK_FWP);
+
+       frsh_network_budget_to_bytes(FRSH_NETPF_FWP, &basic->budget, &bytes);
+       vparams.budget = bytes;
+       vparams.period = basic->period;
+       vparams.ac_id = fwp_sched->ac_id;
+       if (fwp) {
+               vparams.src.s_addr = fwp->src;
+               snprintf(src, sizeof(src), "%s", inet_ntoa(vparams.src));
+       }
+       /* Create vres */
+       if ((rv = fwp_vres_create(&vparams, &fwp_vres)))
+               return (rv == -1) ? errno : rv;
+
+       vres->priv = fwp_vres;
+
+       fres_contract_id_to_string(id, &vres->id, sizeof(id));
+       ul_logmsg("Creating FWP VRes (id=%s, period=%ld ms, budget=%ld bytes AC=%d src=%s)\n",
+               id, fosa_rel_time_to_msec(basic->period), 
+                 vparams.budget, vparams.ac_id, src);
+       
+       return 0;
+}
+
+static int cancel_vres(fres_vres_t *vres, void *priv)
+{
+       struct fwp_vres *       fwp_vres;
+       fres_block_basic *basic;
+       char id[40];
+
+       fwp_vres = (struct fwp_vres *) vres->priv;
+       fwp_vres_destroy(fwp_vres);
+
+       basic = fres_contract_get_basic(vres->allocated);
+       fres_contract_id_to_string(id, &vres->id, sizeof(id));
+       ul_logmsg("Canceling FWP VRes (id=%s, period=%ld ms, budget=%ld bytes)\n",
+              id, fosa_rel_time_to_msec(basic->period), basic->budget.tv_sec);
+
+       return 0;
+}
+
+int change_vres(fres_vres_t *vres, void *priv)
+{
+       char id[40];
+       fres_block_basic *basic;
+       fres_block_fwp_sched *fwp_sched;
+       fwp_vres_params_t vparams;
+       struct fwp_vres *fwp_vres;
+       int rv;
+       size_t bytes;
+       
+       /* Prepare vres parameters */
+       basic = fres_contract_get_basic(vres->new);
+       fwp_sched = fres_contract_get_block(vres->new, FRES_BLOCK_FWP_SCHED);
+
+       frsh_network_budget_to_bytes(FRSH_NETPF_FWP, &basic->budget, &bytes);
+       vparams.budget = bytes;
+       vparams.period = basic->period;
+       vparams.ac_id = fwp_sched->ac_id;
+       fwp_vres = vres->priv;
+
+       /* Changing vres */
+       if ((rv = fwp_vres_set_params(fwp_vres, &vparams))) {
+               return  rv;
+       }
+
+       fres_contract_id_to_string(id, &vres->id, sizeof(id));
+       printf("Changing FWP VRes (id=%s, period=%ld ms, budget=%ld bytes AC=%d)\n",
+               id, fosa_rel_time_to_msec(basic->period), 
+               vparams.budget, vparams.ac_id);
+
+       vres->perceived = vres->new;
+       
+       return 0;
+}
+
+static struct fres_allocator fwp_allocator = {
+       .res_type = FRSH_RT_NETWORK,
+       .res_id = FRSH_NETPF_FWP,
+       .create_vres = create_vres,
+       .cancel_vres = cancel_vres,
+       .change_vres = change_vres,
+       .priv = NULL
+};
+
+int fra_fwp_init(void)
+{
+       fres_block_register_fwp();
+       return fra_register(&fwp_allocator);
+}
diff --git a/src/fwp/fwp/lib/frsh_fwp/fwp_idl.idl b/src/fwp/fwp/lib/frsh_fwp/fwp_idl.idl
new file mode 100644 (file)
index 0000000..26577c2
--- /dev/null
@@ -0,0 +1,26 @@
+/**
+ * @file   fwp_idl.idl
+ * @author Martin Molnar <molnam1@fel.cvut.cz>
+ * @date   Thu Oct 30 14:27:12 2008
+ * 
+ * @brief  Contract data block for fwp resource
+ * 
+ * 
+ */
+module fres {
+       module block {
+               /// Data passed from FWP manager to allocator.
+               struct fwp_sched {
+                       octet ac_id;
+               };
+               /// Data passed by application to manager and/or
+               /// allocator.
+               struct fwp {
+                       /// Non-zero value speciefies source address
+                       /// used for sending packets. This value is
+                       /// used to set ipi_spec_dst field of
+                       /// IP_PKTINFO socket option - see ip(7).
+                       long src;
+               };
+       };
+};
diff --git a/src/fwp/fwp/lib/frsh_fwp/fwp_res.h b/src/fwp/fwp/lib/frsh_fwp/fwp_res.h
new file mode 100644 (file)
index 0000000..405f9d9
--- /dev/null
@@ -0,0 +1,65 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#ifndef FWP_RES_H
+#define FWP_RES_H
+
+#include <forb.h>
+#include <fcb.h>
+#include <frsh_distributed.h>
+#include "fwp_idl.h"
+
+int fra_fwp_init();
+int fres_block_register_fwp();
+
+#include <fres_container.h>
+FRES_CONTAINER_ACCESSOR(FWP_SCHED, fwp_sched)
+FRES_CONTAINER_ACCESSOR(FWP, fwp)
+
+#include <fres_contract.h>
+FRES_CONTRACT_ACCESSOR(fwp_sched)
+FRES_CONTRACT_ACCESSOR(fwp)
+
+#endif /* FWP_RES_H */
diff --git a/src/fwp/fwp/lib/fwp/Doxyfile b/src/fwp/fwp/lib/fwp/Doxyfile
new file mode 100644 (file)
index 0000000..d5cf1d2
--- /dev/null
@@ -0,0 +1,285 @@
+# Doxyfile 1.5.4
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING      = UTF-8
+PROJECT_NAME           = FWP
+PROJECT_NUMBER         = 
+OUTPUT_DIRECTORY       = doc
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = YES
+STRIP_FROM_PATH        =
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = YES
+QT_AUTOBRIEF           = YES
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_JAVA   = NO
+BUILTIN_STL_SUPPORT    = NO
+CPP_CLI_SUPPORT        = NO
+SIP_SUPPORT            = NO
+DISTRIBUTE_GROUP_DOC   = YES
+SUBGROUPING            = YES
+TYPEDEF_HIDES_STRUCT   = NO
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+EXTRACT_ANON_NSPACES   = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = NO
+FILE_VERSION_FILTER    = 
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = 
+INPUT_ENCODING         = UTF-8
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.C \
+                         *.CC \
+                         *.C++ \
+                         *.II \
+                         *.I++ \
+                         *.H \
+                         *.HH \
+                         *.H++ \
+                         *.CS \
+                         *.PHP \
+                         *.PHP3 \
+                         *.M \
+                         *.MM \
+                         *.PY \
+                         *.F90
+RECURSIVE              = YES
+EXCLUDE                = _build _compiled fna fosa frsh utils
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXCLUDE_SYMBOLS        = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS              = NO
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+HTML_DYNAMIC_SECTIONS  = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = YES
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = NO
+MSCGEN_PATH            = 
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = YES
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = YES
+CALLER_GRAPH           = YES
+GRAPHICAL_HIERARCHY    = YES
+DIRECTORY_GRAPH        = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+DOT_GRAPH_MAX_NODES    = 50
+MAX_DOT_GRAPH_DEPTH    = 1000
+DOT_TRANSPARENT        = YES
+DOT_MULTI_TARGETS      = NO
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/src/fwp/fwp/lib/fwp/Makefile b/src/fwp/fwp/lib/fwp/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/lib/fwp/Makefile.omk b/src/fwp/fwp/lib/fwp/Makefile.omk
new file mode 100644 (file)
index 0000000..4098655
--- /dev/null
@@ -0,0 +1,13 @@
+#lib_LIBRARIES = fwp
+shared_LIBRARIES = fwp
+CFLAGS += -D_FWP_INTERNALS_ #-DFWP_WITHOUT_CONTNEGT
+SUBDIRS = tests 
+#LDFLAGS = -lpthread  -lrt
+fwp_SOURCES = fwp_utils.c fwp_vres.c fwp_msgb.c fwp_msgq.c fwp_endpoint.c fwp.c
+include_HEADERS= fwp_conf.h fwp_confdefs.h fwp_endpoint.h fwp_vres.h fwp.h fwp_msgb.h\
+                       fwp_msgq.h fwp_utils.h
+
+include_HEADERS += fwp_debug.h # This file (and maybe even some        \
+                                others) should not be exported!
+
+lib_LOADLIBES+= pthread rt ulut 
diff --git a/src/fwp/fwp/lib/fwp/fwp.c b/src/fwp/fwp/lib/fwp/fwp.c
new file mode 100644 (file)
index 0000000..03e5634
--- /dev/null
@@ -0,0 +1,65 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#include "fwp_conf.h"
+#include "fwp_vres.h"
+#include "fwp_utils.h"
+#include <ul_logreg.h>
+#include "fwp_debug.h"
+
+ul_log_domain_t ulogd_fwp = {UL_LOGL_MSG, "fwp"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(init_ulogd_fwo, ulogd_fwp);
+
+int fwp_init()
+{
+       return 0;
+}
+
+int fwp_done()
+{
+       FWP_DEBUG("FWP done\n");
+       /* TODO: Cancel all contracts */
+       return 0;
+}
diff --git a/src/fwp/fwp/lib/fwp/fwp.h b/src/fwp/fwp/lib/fwp/fwp.h
new file mode 100644 (file)
index 0000000..7d671af
--- /dev/null
@@ -0,0 +1,81 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+/**
+@mainpage
+
+@section Introduction
+
+FRESCOR WLAN protocol (FWP) allows the application to specify its requirements 
+(number of bytes transmitted per period, deadline, etc.) for communication over 
+IEEE 802.11 WLAN network and proides the mechanism that tries to fulfill them if 
+they are feasible.
+
+FWP’s goal is to adapt applications to the current conditions on WLAN network 
+rather than guaranteeing realtime behavior. FWP is designed to work on 
+hardware conforming to WMM specification which defines EDCA medium access 
+mechanism. EDCA extends legacy DCF function by prioritized medium access so 
+that the packets in higher priority queue have higher probability to access 
+the medium first.
+
+*/
+
+#ifndef _FWP_H
+#define _FWP_H
+
+#ifndef _FWP_CONFDEFS_H
+//#error fwp_confdefs.h not included
+#endif
+
+
+#include "fwp_conf.h"
+#include "fwp_vres.h"
+#include "fwp_endpoint.h"
+
+int fwp_init(void);
+int fwp_done(void);
+
+#endif /* _FWP_H */
diff --git a/src/fwp/fwp/lib/fwp/fwp_conf.h b/src/fwp/fwp/lib/fwp/fwp_conf.h
new file mode 100644 (file)
index 0000000..bc2a9ed
--- /dev/null
@@ -0,0 +1,70 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#ifndef _FWP_CONF_H
+#define _FWP_CONF_H
+
+#define FWP_AC_NUM     4
+#define FWP_MSGQ_SIZE (1<<11)  /* Must be power of 2 */
+
+#define FWP_MY_ADDR_DEFAULT    "127.0.0.1"
+#define FWP_MNGR_ADDR_DEFAULT  "127.0.0.1"
+
+typedef 
+struct {
+       unsigned int max_vres;
+       unsigned int max_endpoints;
+       unsigned int mngt;
+       char         my_addr[16];
+       unsigned int my_stream_id;
+       char         mngr_addr[16];
+       unsigned int mngr_stream_id;
+       unsigned int my_node_id;
+       unsigned int mngr_node_id;
+} fwp_configuration_table_t;
+
+extern fwp_configuration_table_t fwp_configuration;
+
+#endif /* _FWP_CONF_H */
diff --git a/src/fwp/fwp/lib/fwp/fwp_confdefs.h b/src/fwp/fwp/lib/fwp/fwp_confdefs.h
new file mode 100644 (file)
index 0000000..26bfea2
--- /dev/null
@@ -0,0 +1,119 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#ifndef _FWP_CONFDEFS_H
+#define _FWP_CONFDEFS_H
+
+#include "fwp_conf.h"
+
+/** Number of ACs */
+#ifndef CONFUGURE_FWP_AC_NUM
+#define CONFIGURE_FWP_AC_NUM   4
+#endif
+
+/* Size of message queue (in message units). MUST BE POWER OF 2!! */
+#ifndef CONFIGURE_FWP_MSGQ_SIZE
+#define CONFIGURE_FWP_MSGQ_SIZE 32 
+#endif
+
+/* Maximal number of fwp vres per application. */
+#ifndef CONFIGURE_FWP_VRES_MAXIMUM
+#define CONFIGURE_FWP_VRES_MAXIMUM 20
+#endif
+
+/* Maximal number of fwp contract in contract table */
+#ifndef CONFIGURE_FWP_CONTRACTS_MAXIMUM 
+#define CONFIGURE_FWP_CONTRACTS_MAXIMUM 50
+#endif
+
+/* Maximal number of fwp endpoint per application. */
+#ifndef CONFIGURE_FWP_ENDPOINTS_MAXIMUM 
+#define CONFIGURE_FWP_ENDPOINTS_MAXIMUM 50
+#endif
+
+/** Turn on/off FWP mnanagement */
+#ifndef CONFIGURE_FWP_MNGT
+#define CONFIGURE_FWP_MNGT 1
+#endif
+
+/** IP Address of interface FWP operates on */
+//#ifndef CONFIGURE_FWP_MY_ADDR
+//#define CONFIGURE_FWP_MY_ADDR "127.0.0.1"
+//#endif
+
+#ifndef CONFIGURE_FWP_MY_STREAM_ID
+#define CONFIGURE_FWP_MY_STREAM_ID 0
+#endif
+
+//#ifndef CONFIGURE_FWP_MNGR_ADDR
+//#define CONFIGURE_FWP_MNGR_ADDR "255.255.255.255"
+//#endif
+
+#ifndef CONFIGURE_FWP_MNGR_STREAM_ID
+#define CONFIGURE_FWP_MNGR_STREAM_ID 3000
+#endif
+
+fwp_configuration_table_t fwp_configuration = {
+       CONFIGURE_FWP_VRES_MAXIMUM,
+       CONFIGURE_FWP_ENDPOINTS_MAXIMUM,
+       CONFIGURE_FWP_MNGT,
+#ifdef CONFIGURE_FWP_MY_ADDR
+       CONFIGURE_FWP_MY_ADDR,
+#else
+       FWP_MY_ADDR_DEFAULT,
+#endif
+       CONFIGURE_FWP_MY_STREAM_ID,
+#ifdef CONFIGURE_FWP_MNGR_ADDR
+       CONFIGURE_FWP_MNGR_ADDR,
+#else
+       FWP_MNGR_ADDR_DEFAULT,
+#endif
+       CONFIGURE_FWP_MNGR_STREAM_ID,
+       0,
+       0
+};
+
+
+#endif /*_FWP_CONFDEFS_H*/
diff --git a/src/fwp/fwp/lib/fwp/fwp_debug.h b/src/fwp/fwp/lib/fwp/fwp_debug.h
new file mode 100644 (file)
index 0000000..cbbe074
--- /dev/null
@@ -0,0 +1,58 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+#ifndef FWP_DEBUG_H
+#define FWP_DEBUG_H
+
+#include <ul_log.h>
+
+extern UL_LOG_CUST(ulogd_fwp);
+
+#define FWP_DEBUG(fmt,args...) ul_logdeb("%s: " fmt, __func__ , ##args)
+#define FWP_ERROR(fmt,args...) ul_logerr("%s: " fmt, __func__ , ##args)
+
+
+#endif
diff --git a/src/fwp/fwp/lib/fwp/fwp_endpoint.c b/src/fwp/fwp/lib/fwp/fwp_endpoint.c
new file mode 100644 (file)
index 0000000..6117d6c
--- /dev/null
@@ -0,0 +1,659 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#include "fwp_endpoint.h"
+#include "fwp_msgb.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include "fwp_utils.h"
+#include "fwp_vres.h"
+#include <frsh_error.h>
+
+#include <pthread.h>
+#include "fwp_debug.h"
+#include "fwp_msgq.h"
+
+typedef unsigned int fwp_endpoint_id_t;
+
+/**
+ * Default fwp endpoint attributes
+ */
+static fwp_endpoint_attr_t fwp_epoint_attr_default ={
+       .reliability = FWP_EPOINT_BESTEFFORT, 
+       .max_connections = 20,
+};
+
+/**
+ * FWP endpoint structure
+ */
+struct fwp_endpoint{
+       /** Fwp endpoint attributes */
+       fwp_endpoint_attr_t     attr;
+       /* Vres this fwp endpoint is bound to */
+       fwp_vres_t              *vres;
+       /** For send enpoint it contains destination address for
+        * receive endpoint it is filled with the msg source address
+        */
+       struct fwp_sockaddr     peer;   
+       /** Source/destination port */
+       unsigned int            port;   
+       /** Destination node */
+       int                     node;
+       /** Socket descriptor.
+        * In case of rebliable epoint it is a listen tcp socket.
+        */
+       int                     sockd; 
+       /** File descriptor array of peers connected 
+        * to this fwp receive endpoint.*/
+       int                     *c_sockd;
+       /**
+        * Number of connections 
+        */
+       unsigned int            nr_connections;
+       /** client fdset */
+       fd_set                  fdset;
+       /** specific operation options*/
+       int                     flags;  
+       /** Forced source address. If non-zero, packets are sent over
+        * the specified interface. */
+       struct in_addr  src;
+};
+
+/**
+ * Allocates endpoint
+ *
+ * \return On success returns fwp endpoint structure. 
+ * On error, NULL is returned. 
+ *
+ */
+static struct fwp_endpoint* fwp_endpoint_alloc()
+{
+       return (struct fwp_endpoint*) calloc(1,sizeof(struct fwp_endpoint));
+}
+
+/**
+ * Allocates endpoint
+ *
+ * \return On success returns endpoint structure. 
+ * On error, NULL is returned. 
+ *
+ */
+static inline void fwp_endpoint_free(struct fwp_endpoint *endpoint)
+{
+       free(endpoint);
+}
+
+/**
+ * Destroy endpoint
+ *
+ * \param[in] epd Endpoint descriptor
+ * \return On success 0 is returned. 
+ * On error, negative error value is returned and errno is set appropriately. 
+ */
+int fwp_endpoint_destroy(struct fwp_endpoint *ep)
+{
+       if (ep->sockd > 0) 
+               close(ep->sockd);
+
+       fwp_endpoint_free(ep);  
+       return 0;
+}
+
+/**
+ * Get endpoint parameters
+ *
+ * \param[in] ep Endpoint descriptor
+ * \param[out] node Node identifier
+ * \param[out] port Port
+ * \param[out] attr Endpoint`s attributes
+ * \return On success 0 is returned. 
+ * On error, negative error value is returned. 
+ */
+int fwp_endpoint_get_params(struct fwp_endpoint *ep, unsigned int *node, 
+                               unsigned int *port, fwp_endpoint_attr_t *attr)
+{
+       if (node) *node = ep->node;
+       if (port) *port = ep->port;
+       if (attr) *attr = ep->attr;
+       
+       return 0;
+}
+
+int fwp_endpoint_attr_init(fwp_endpoint_attr_t *attr)
+{
+       bzero(attr, sizeof(fwp_endpoint_attr_t));
+       *attr = fwp_epoint_attr_default;
+
+       return 0;
+}
+
+/**
+ * Creates send endpoint
+ *
+ * \param[in] node IP address of destination node
+ * \param[in] port UDP port
+ * \param[in] attr Endpoint attributes
+ * \param[out] epp  Pointer to the descriptor of newly created endpoint
+ *
+ * \return Non-negative number on success, -1 on error and sets errno appropriately. 
+ *
+ */
+int fwp_send_endpoint_create(unsigned int node,
+                               unsigned int port, 
+                               fwp_endpoint_attr_t *attr,
+                               struct fwp_endpoint **epoint)
+{      
+       struct sockaddr_in *addr;
+       struct fwp_endpoint *fwp_epoint;
+
+       fwp_epoint = fwp_endpoint_alloc();      
+        if (!fwp_epoint) {
+               errno = ENOMEM;
+               return -1;
+       }
+       
+       /*epoint->type = FWP_SEND_EPOINT;
+       epoint->status = FWP_EPOINT_UNBOUND;
+       epoint->node = node;
+       epoint->port = port;
+       */
+       if (attr)
+               fwp_epoint->attr  = *attr;
+       else
+               fwp_epoint->attr = fwp_epoint_attr_default;
+               
+       addr = (struct sockaddr_in *)&(fwp_epoint->peer.addr);
+       bzero((char*) addr, sizeof(*addr));
+       addr->sin_family = AF_INET;
+       addr->sin_addr.s_addr = node;
+       addr->sin_port = htons(port);
+        fwp_epoint->peer.addrlen = sizeof(struct sockaddr_in);
+       
+       if (fwp_epoint->attr.reliability == FWP_EPOINT_RELIABLE) {
+               fwp_epoint->sockd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+               if (fwp_epoint->sockd < 0) {
+                       goto err;
+               }
+       } else {
+               fwp_epoint->sockd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+               if (fwp_epoint->sockd < 0) {
+                       goto err;
+               }
+       
+               /* Enable broadcasts */
+               /*unsigned int yes = 1;
+               if (setsockopt(fwp_epoint->sockd,SOL_SOCKET, SO_BROADCAST, 
+                              &yes, sizeof(yes)) == -1) {
+                       FWP_DEBUG("setsockopt(SO_BROADCAST): %s", strerror(errno));
+                       goto err;
+               }*/
+       
+       }
+       
+       unsigned int yes = 1;
+       if (setsockopt(fwp_epoint->sockd,SOL_SOCKET, SO_REUSEADDR, 
+                              &yes, sizeof(yes)) == -1) {
+                       FWP_DEBUG("setsockopt(SO_REUSEADDR): %s", strerror(errno));
+                       goto err;
+       }
+
+#if 0
+       /* TODO: Allow using connect if it is specified in attr */
+       if (connect(fwp_epoint->sockd,
+                       (struct sockaddr*) &fwp_epoint->peer.addr, 
+                       fwp_epoint->peer.addrlen)) {
+               FWP_DEBUG("FWp connect error\n"); 
+               goto err;
+       }
+#endif
+       FWP_DEBUG("FWP Send endpoint created.\n"); 
+
+#ifdef FWP_WITHOUT_CONTNEGT
+       /* Create vres with default parameters */
+       FWP_DEBUG("Creating default vres\n");
+       if (fwp_vres_create(&fwp_vres_params_default, &fwp_epoint->vresd)) {
+               goto err;
+       }
+       
+       fwp_send_endpoint_bind(fwp_epoint, fwp_epoint->vresd);
+#endif
+       
+       *epoint = fwp_epoint;
+       return fwp_epoint->sockd;               
+err:
+       fwp_endpoint_destroy(fwp_epoint);
+       return -1;      
+}
+
+/**
+ * Creates receive endpoint
+ *
+ * \param[in] port UDP port
+ * \param[in] attr Endpoint attributes
+ * \param[out] epointdp  Pointer to the descriptor of newly created endpoint
+ *
+ * \return Non-negative number on success, -1 on error and errno is set.
+ */
+int fwp_receive_endpoint_create(unsigned int port,
+                               fwp_endpoint_attr_t *attr,
+                               struct fwp_endpoint **epp)
+{
+       struct sockaddr_in *addr;
+       struct fwp_endpoint *fwp_epoint;
+
+       fwp_epoint = fwp_endpoint_alloc();      
+        if (!fwp_epoint) {
+               errno = ENOMEM;
+               return -1;
+       }
+       
+       /*epoint->type = FWP_RECV_EPOINT;
+       epoint->status = FWP_EPOINT_UNBOUND;*/
+       
+       if (attr)
+               fwp_epoint->attr  = *attr;
+       else
+               fwp_epoint->attr = fwp_epoint_attr_default;
+
+       addr = (struct sockaddr_in *) &(fwp_epoint->peer.addr);
+       addr->sin_family = AF_INET;
+       /* TODO: set listen interface, maybe through config struct*/
+       addr->sin_addr.s_addr = FWP_ANY_NODE;
+       fwp_epoint->port  = addr->sin_port = htons(port);
+        fwp_epoint->peer.addrlen = sizeof(struct sockaddr_in);
+       
+       if (fwp_epoint->attr.reliability == FWP_EPOINT_RELIABLE) {
+               if ((fwp_epoint->sockd = socket(PF_INET, SOCK_STREAM, 
+                                               IPPROTO_TCP)) < 0) {
+                       FWP_ERROR("Unable to open socket: %s", strerror(errno));
+                       goto err;
+               }       
+               
+               int yes = 1;
+               if (setsockopt(fwp_epoint->sockd,SOL_SOCKET, SO_REUSEADDR,
+                              &yes, sizeof(yes)) == -1) {
+                       FWP_ERROR("setsockopt(SO_REUSEADDR):%s",strerror(errno));
+                       goto err;
+               }
+
+               if (bind(fwp_epoint->sockd, (struct sockaddr*) &fwp_epoint->peer.addr, 
+                               fwp_epoint->peer.addrlen) == -1) {
+                       FWP_ERROR("Bind error: %s", strerror(errno));
+                       /* TODO: remove all error messages from all libraries */
+                       goto err;
+               }
+               
+               if (listen(fwp_epoint->sockd, fwp_epoint->attr.max_connections)){
+                       FWP_ERROR("Error on listen call: %s\n", strerror(errno));
+                       goto err;
+               }
+               
+               FD_ZERO(&fwp_epoint->fdset);
+               /*add listen socket */
+               FD_SET(fwp_epoint->sockd, &fwp_epoint->fdset); 
+               fwp_epoint->c_sockd = 
+                               (int*)malloc(fwp_epoint->attr.max_connections);
+               bzero(fwp_epoint->c_sockd, fwp_epoint->attr.max_connections);
+               fwp_epoint->nr_connections = 0;
+
+               FWP_DEBUG("Reliable receive endpoint port=%d created.\n", 
+                               fwp_epoint->port); 
+       } else {
+               if ((fwp_epoint->sockd = socket(PF_INET, SOCK_DGRAM, 
+                                               IPPROTO_UDP)) < 0) {
+                       FWP_ERROR("Unable to open socket: %s", strerror(errno));
+                       goto err;
+               }
+               
+               if (bind(fwp_epoint->sockd, 
+                       (struct sockaddr*) &fwp_epoint->peer.addr, 
+                       fwp_epoint->peer.addrlen) == -1) {
+                       
+                       FWP_ERROR("Bind error: %s", strerror(errno));
+                       goto err;
+               }
+               FWP_DEBUG("Best-Effort receive endpoint port=%d created.\n", 
+                               fwp_epoint->port); 
+       }
+               
+       /*if (setsockopt(epoint->sockd, SOL_SOCKET, SO_RCVBUF, 
+                       &rcvbuf_size, sizeof(rcvbuf_size)) == -1) {
+               
+               FWP_ERROR("Unable to set socket buffer size: %s", strerror(errno));
+               return -1;
+       }else {
+               FWP_DEBUG("Receive endpoint buffer size is set.\n");
+       }
+       */
+       
+       getsockname(fwp_epoint->sockd, (struct sockaddr*)&fwp_epoint->peer.addr, 
+                       &fwp_epoint->peer.addrlen);
+
+       addr = (struct sockaddr_in*) fwp_epoint->peer.addr;
+       fwp_epoint->port = ntohs(addr->sin_port);
+       FWP_DEBUG("Recv port= %d\n",ntohs(addr->sin_port));     
+       *epp = fwp_epoint;
+       return fwp_epoint->sockd;
+err:
+       fwp_endpoint_destroy(fwp_epoint);
+       return -1;
+}
+
+/**
+ * Binds send endpoint to vres
+ *
+ * \param[in] vres identifier of vres
+ * \param[in] ep send endpoint identifier
+ *
+ * \return On success returns 0. On error, -1 and errno is set appropriately.
+ */
+int fwp_send_endpoint_bind(struct fwp_endpoint *ep, fwp_vres_t *vres)
+{
+       int rv = 0;
+
+       if (ep->vres)
+               return FRSH_ERR_ALREADY_BOUND;
+       
+       ep->vres = vres;
+       rv = fwp_vres_bind(vres, ep, ep->sockd, &ep->src);
+
+       return rv;
+}
+
+/**
+ * Unbinds send endpoint from vres
+ *
+ * \param[in] epointd Send endpoint descriptor 
+ * \return On success returns 0. On error, -1 is returned and errno is set appropriately.
+ *
+ */
+int fwp_send_endpoint_unbind(struct fwp_endpoint *ep)
+{
+       int rv = 0;
+
+       /* unlink epoint-vres mutually */
+       if ((rv = fwp_vres_unbind(ep->vres)) < 0) 
+               return rv;
+
+       return 0;
+}
+
+/**
+ * Accepts (TCP) client connection to receive endpoint
+ *
+ * \param[in] epointd Pointer to fwp endpoint
+ * \return
+ * On success, it returns zero.  
+ *
+ */
+static int fwp_receive_endpoint_accept(struct fwp_endpoint *fwp_epoint)
+{
+       int csockd;
+//     struct fwp_endpoint *fwp_epoint = epointd;
+       fwp_sockaddr_t  peer;
+       int i;
+
+       if (fwp_epoint->nr_connections == fwp_epoint->attr.max_connections)
+               return -1;
+
+       peer.addrlen = sizeof(struct sockaddr_in);
+       csockd = accept(fwp_epoint->sockd, (struct sockaddr*)peer.addr,
+                       &peer.addrlen);
+       
+       if (csockd < 0) {
+               FWP_ERROR("Error on accept: %s\n", strerror(errno));
+               return errno;   
+       }               
+
+       FWP_DEBUG("New connection accepted\n");
+       /* find free place */           
+       i = 0;
+       while ((fwp_epoint->c_sockd[i])&& (i < fwp_epoint->nr_connections)) 
+                               i++;
+       fwp_epoint->c_sockd[i] = csockd; 
+       fwp_epoint->nr_connections++;
+               
+       FD_SET(csockd, &fwp_epoint->fdset);
+       return 0;       
+} 
+
+/**
+ * Receives message from stream (TCP)
+ *
+ * \param[in] epointd Descriptor of endpoint
+ * \param[in] buffer Buffer to store message
+ * \param[in] buffer_size Size of buffer
+ *
+ * \return
+ * On success, it returns number of received bytes.  
+ * On error, -1 is returned and errno is set appropriately.
+ *
+ */
+int fwp_recv_conn(struct fwp_endpoint *ep, void *buffer, 
+                       size_t buffer_size)
+{
+       fwp_sockaddr_t *peer = &ep->peer;
+       fd_set fdset = ep->fdset;
+       ssize_t len;
+       int i;
+
+       FWP_DEBUG("Checking for tcp data\n");
+       for (i = 0; i < ep->nr_connections; i++) {
+               if (!FD_ISSET(ep->c_sockd[i], &fdset)) {
+                       continue;       
+               }       
+                       
+               FWP_DEBUG("Prepare to receive tcp data\n");
+               peer->addrlen = sizeof(struct sockaddr_in);
+
+               len = recvfrom(ep->c_sockd[i], buffer, buffer_size, 0,
+                              (struct sockaddr*)&peer->addr, &peer->addrlen);
+               if (len < 0) /* Error */
+                       return len;
+               
+               FWP_DEBUG("Received tcp data\n");
+               if (len)
+                       return len;
+       
+               /* tcp connection closed */
+               FWP_DEBUG("Connection closed\n");
+               FD_CLR(ep->c_sockd[i], &ep->fdset);
+               memcpy(ep->c_sockd+i, ep->c_sockd+i+1, 
+                       sizeof(int)*(ep->nr_connections -i-1));
+               ep->nr_connections--;
+               return 0;
+       }
+       return 0;
+}
+
+/**
+ * Receives message
+ *
+ * \param[in] epointd Descriptor of endpoint
+ * \param[in] buffer Buffer to store message
+ * \param[in] buffer_size Size of buffer
+ *
+ * \return
+ * On success, it returns number of received bytes.  
+ * On error, -1 is returned and errno is set appropriately.
+ *
+ */
+ssize_t fwp_recv(struct fwp_endpoint *ep,
+                       void *buffer, const size_t buffer_size,
+                       unsigned int *from, int flags)
+{
+       fwp_sockaddr_t *peer = &ep->peer;
+       struct sockaddr_in *addr = (struct sockaddr_in*) ep->peer.addr;
+       ssize_t len;
+       fd_set fdset;
+       
+       /*if (!fwp_endpoint_is_valid(epointd)) {
+               errno = EINVAL;
+               return -1;
+       }*/
+       
+       if (ep->attr.reliability == FWP_EPOINT_BESTEFFORT) {    
+               len = recvfrom(ep->sockd, buffer, buffer_size, 0,
+                              (struct sockaddr*)&peer->addr, &peer->addrlen);
+               *from = addr->sin_addr.s_addr;
+               return len;
+       }
+       
+       while (1){
+               /* FWP_EPOINT_RELIABLE */
+               fdset = ep->fdset;
+               if (select(FD_SETSIZE, &fdset, (fd_set *)0, 
+                          (fd_set *)0, NULL) < 0) {
+               
+                       FWP_ERROR("Error in select: %s", strerror(errno));
+                       return -1;
+               }
+       
+               if (FD_ISSET(ep->sockd, &fdset)) { /* is it listen socket? */
+                       fwp_receive_endpoint_accept(ep);
+                       continue;
+               }
+
+               /* Check client TCP sockets */
+               len = fwp_recv_conn(ep, buffer, buffer_size);
+               if (len) {
+                       *from = addr->sin_addr.s_addr;
+                       return len;
+               }
+       }
+}
+/** 
+ * Physically send the message.
+ *
+ * This function should be called either by fwp_send_sync()/async() of
+ * by VRES to send delayed messaged.
+ * 
+ * @param ep 
+ * @param data 
+ * @param size 
+ * 
+ * @return 
+ */
+ssize_t fwp_endpoint_do_send(struct fwp_endpoint *ep,
+                            const void *data, const size_t size)
+{
+       struct iovec  iov;
+       struct msghdr msg = {0};
+       ssize_t ret;
+       char cmsg_buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
+
+       iov.iov_base = (void*)data;
+       iov.iov_len = size;
+
+       msg.msg_name = &ep->peer.addr;
+       msg.msg_namelen = ep->peer.addrlen;
+       msg.msg_iov = &iov;
+       msg.msg_iovlen = 1;
+
+       if (ep->src.s_addr != 0) {
+               struct cmsghdr *cmsg;
+               struct in_pktinfo *ipi;
+
+               memset(cmsg_buf, 0, sizeof(cmsg_buf));
+
+               msg.msg_control = cmsg_buf;
+               msg.msg_controllen = sizeof(cmsg_buf);
+
+               cmsg = CMSG_FIRSTHDR(&msg);
+
+               cmsg->cmsg_level = SOL_IP;
+               cmsg->cmsg_type = IP_PKTINFO;
+               cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+
+               ipi = (struct in_pktinfo*)CMSG_DATA(cmsg);
+               ipi->ipi_spec_dst = ep->src;
+       }
+       ret = sendmsg(ep->sockd, &msg, 0);
+       return ret;
+}
+
+/**
+ * Sends message through vres
+ *
+ * \param[in] epointd Endpoint descriptor
+ * \param[in] msg Message to sent
+ * \param[in] size Message size
+ *
+ * \return
+ * On success, it returns zero.  
+ * On error, -1 is returned and errno is set appropriately.
+ *
+ */
+int fwp_send_async(struct fwp_endpoint *ep, const void *msg, size_t size)
+{
+       int ret;
+
+       if (!ep->vres)
+               return FRSH_ERR_NOT_BOUND;
+
+       ret = fwp_vres_consume_budget(ep->vres, size, false);
+       if (ret == 0)
+               ret = fwp_endpoint_do_send(ep, msg, size);
+       else if (ret == 1)
+               ret = fwp_vres_enqueue(ep->vres, ep, msg, size);
+       return ret;
+}
+
+int fwp_send_sync(struct fwp_endpoint *ep, const void *msg, size_t size)
+{
+       int ret;
+
+       if (!ep->vres)
+               return FRSH_ERR_NOT_BOUND;
+
+       ret = fwp_vres_consume_budget(ep->vres, size, true);
+       if (ret)
+               return ret;
+       ret = fwp_endpoint_do_send(ep, msg, size);
+       return ret;
+}
+
diff --git a/src/fwp/fwp/lib/fwp/fwp_endpoint.h b/src/fwp/fwp/lib/fwp/fwp_endpoint.h
new file mode 100644 (file)
index 0000000..c8a298f
--- /dev/null
@@ -0,0 +1,109 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#ifndef _FWP_ENDPOINT_H
+#define _FWP_ENDPOINT_H
+
+#define FWP_ANY_NODE INADDR_ANY
+
+typedef enum {
+       FWP_EPOINT_BESTEFFORT   = 0,
+       FWP_EPOINT_RELIABLE     = 1,
+} fwp_endpoint_reliability_t;
+
+struct fwp_endpoint;
+
+typedef unsigned int fwp_addr_t;
+
+/**
+ * Endpoint attributes
+ */
+typedef
+struct fwp_endpoint_attr {
+       /** Specifies whether fwp endpoint is reliable (TCP) or not (UDP)*/
+       unsigned int reliability;
+       /** Specifies max number of allowed connections (for TCP only) */
+       unsigned int max_connections;
+} fwp_endpoint_attr_t;
+
+#include "fwp_vres.h"
+
+int fwp_endpoint_get_params(struct fwp_endpoint *ep, unsigned int *node, 
+                               unsigned int *port, fwp_endpoint_attr_t *attr);
+int fwp_send_endpoint_create(unsigned int node, unsigned int port,
+                               fwp_endpoint_attr_t *attr, 
+                               struct fwp_endpoint **epoint);
+int fwp_receive_endpoint_create(/*unsigned int node,*/ unsigned int port,
+                               fwp_endpoint_attr_t *attr, 
+                               struct fwp_endpoint **epoint);
+int fwp_endpoint_destroy(struct fwp_endpoint *ep);
+
+int fwp_send_endpoint_bind(struct fwp_endpoint *ep, fwp_vres_t *vres);
+int fwp_send_endpoint_unbind(struct fwp_endpoint *ep);
+
+ssize_t fwp_recv(struct fwp_endpoint *ep,
+                       void *buffer, const size_t buffer_size,
+                       unsigned int *from, int flags);
+int fwp_send_sync(struct fwp_endpoint *ep, const void *msg, const size_t size);
+int fwp_send_async(struct fwp_endpoint *ep, const void *msg, const size_t size);
+ssize_t fwp_endpoint_do_send(struct fwp_endpoint *ep,
+                            const void *data, const size_t size);
+int fwp_endpoint_attr_init(fwp_endpoint_attr_t *attr);
+
+static inline int fwp_endpoint_attr_setreliability(fwp_endpoint_attr_t *attr, 
+                                                       int reliability)
+{
+       attr->reliability = reliability;
+       return 0;
+}
+
+/* Sets queueing policy */
+/*int fwp_endpoint_attr_setqpolicy(fwp_endpoint_attr_t *attr);*/
+#ifdef _FWP_INTERNALS_
+
+int fwp_endpoint_table_init(unsigned int nr_endpoints);
+
+#endif /*_FWP_INTERNALS_*/
+#endif /*_FWP_ENDPOINT_H */ 
diff --git a/src/fwp/fwp/lib/fwp/fwp_msgb.c b/src/fwp/fwp/lib/fwp/fwp_msgb.c
new file mode 100644 (file)
index 0000000..5aa9bb6
--- /dev/null
@@ -0,0 +1,221 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+/**
+ * \file fwp_msgb.c
+ *
+ * Routines for manipulation with fwp message buffer (msgb)
+ *
+ */
+
+#include "fwp_msgb.h"
+#include "fwp_utils.h"
+#include <stdlib.h>
+
+/*unsigned char* fwp_msgb_dealloc(size_t buf_size) */
+/*unsigned char* fwp_msgb_pool_init(size_t buf_size) */
+
+/**
+ * Allocates msgb.
+ *
+ * \param buf_size Size of msgb
+ * \return Allocated msgb
+ *
+ */
+struct fwp_msgb* fwp_msgb_alloc(size_t buf_size)
+{
+       struct fwp_msgb* msgb;
+
+       /*fwp_msgb_pool_dequeue; other choice*/
+       msgb = (struct fwp_msgb*) malloc(sizeof(struct fwp_msgb) + buf_size);
+       if (!msgb)
+               return NULL;
+       
+       msgb->buffer_size = buf_size;
+       msgb->len = 0;
+       msgb->data = (unsigned char*) msgb + sizeof(struct fwp_msgb);
+       msgb->tail = msgb->data;
+       
+       return msgb;
+}
+
+/**
+ * Deallocates msgb.
+ *
+ * \param msgb Pointer to msgb
+ *
+ */
+void fwp_msgb_free(struct fwp_msgb *msgb)
+{
+       free((void*) msgb);
+       msgb = NULL;
+}
+
+/**
+ * Routine is usually called after putting data of length len to msgb 
+ * to adjust internal tail pointer and len fields of msgb
+ *
+ * \param msgb Pointer to msgb
+ * \param len The lenght data put to msgb 
+ * \return Previous tail pointer
+ *
+ */
+unsigned char* fwp_msgb_put(struct fwp_msgb *msgb, unsigned int len)
+{
+       unsigned char *tmp= msgb->tail;
+       
+       msgb->tail+=len;
+       msgb->len+=len;
+       return tmp;
+}
+
+/**
+ * Routine is usually called after reading data of lenght len from msgb to 
+ * adjust internal data pointer and len of msgb
+ *
+ * \param msgb Pointer to msgb
+ * \param len The lenght data 
+ * \return Previous tail pointer on NULL in case of lack of space in the buffer.
+ *
+ */
+unsigned char* fwp_msgb_pull(struct fwp_msgb *msgb, unsigned int len)
+{
+       if (len > msgb->len)
+               return NULL;
+       
+       msgb->len -= len;
+       return msgb->data += len;
+}
+
+/**
+ * Routine is usually called after fwp_msgb_reserve after reserved area is filled 
+ * adjust pointers 
+ *
+ * \param msgb Pointer to msgb
+ * \param len The lenght data 
+ * \return Current data pointer
+ *
+ */ 
+unsigned char* fwp_msgb_push(struct fwp_msgb* msgb, unsigned int len)
+{
+       msgb->data-=len;
+       msgb->len+=len;
+       return msgb->data;
+}
+
+unsigned char* fwp_msgb_shift(struct fwp_msgb *msgb, unsigned int len)
+{
+       if (msgb->data + len > msgb->tail)
+               return NULL;
+       
+       return msgb->data += len;
+}
+
+/**
+ * Sets data pointer to the start of buffer
+ *
+ * \param msgb Pointer to msgb
+ *
+ */
+void fwp_msgb_reset_data_pointer(struct fwp_msgb *msgb)
+{
+       msgb->data = (unsigned char*) msgb + sizeof(struct fwp_msgb);
+}
+
+/**
+ * Sets data pointer to the start of buffer and the length of used data to zero
+ *
+ * \param msgb Pointer to msgb
+ */
+void fwp_msgb_reset_data(struct fwp_msgb* msgb)
+{
+       msgb->len = 0;
+       msgb->data = (unsigned char*) msgb + sizeof(struct fwp_msgb);
+       msgb->tail = msgb->data;
+}
+
+/**
+ * Reserve place of length len in msgb
+ *
+ * \param msgb Pointer to msgb
+ * \param len The lenght data 
+ */
+void fwp_msgb_reserve(fwp_msgb_t *msgb, unsigned int len)
+{
+       msgb->data+=len;
+       msgb->tail+=len;
+}
+
+/*struct fwp_socket* fwp_socket_create(struct sockaddr *_addr, socklen_t _addrlen)
+{
+       struct fwp_socket* fwpsock;
+       unsigned char *addr;
+       
+       fwpsock = (struct fwp_socket*) malloc(sizeof(struct fwp_socket) + 
+                                             _addrlen);
+       if (!fwpsock)
+               return NULL;
+       
+       addr = (unsigned char*) fwpsock + sizeof(struct fwp_socket);
+       memcpy(addr, (void*) _addr, _addrlen);
+
+       fwpsock->addr = (struct sockaddr*) addr;
+       fwpsock->addrlen = _addrlen;
+
+       return fwpsock;
+}
+
+inline void fwp_socket_set(struct fwp_socket *fwpsock, struct sockaddr *_addr, 
+                                 socklen_t _addrlen)
+{      
+       fwpsock->addr = _addr;
+       fwpsock->addrlen = _addrlen;
+}
+
+void fwp_socket_free(struct fwp_socket *fwpsock)
+{
+       free((void*)fwpsock);
+       fwpsock = NULL;
+}*/
diff --git a/src/fwp/fwp/lib/fwp/fwp_msgb.h b/src/fwp/fwp/lib/fwp/fwp_msgb.h
new file mode 100644 (file)
index 0000000..f57a4b7
--- /dev/null
@@ -0,0 +1,87 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#ifndef _FWP_MSGB_H
+#define _FWP_MSGB_H
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#define ADDRLEN_MAX 30
+
+typedef
+struct fwp_sockaddr{
+       char            addr[ADDRLEN_MAX];
+       socklen_t       addrlen;
+} fwp_sockaddr_t;
+
+/**
+ * Message buffer structure
+ */
+typedef
+struct fwp_msgb {
+       size_t                  buffer_size;
+       size_t                  len;            /**< msg data length*/
+       unsigned char           *data;          /**< msg data */
+       unsigned char           *tail;          /**< msg data end*/
+} fwp_msgb_t;
+
+struct fwp_msgb* fwp_msgb_alloc(size_t buf_size);
+void fwp_msgb_free(struct fwp_msgb* msgb);
+
+unsigned char* fwp_msgb_put(struct fwp_msgb *msgb, unsigned int len);
+unsigned char* fwp_msgb_pull(struct fwp_msgb *msgb, unsigned int len);
+unsigned char* fwp_msgb_push(struct fwp_msgb* msgb, unsigned int len);
+void fwp_msgb_reset_data_pointer(struct fwp_msgb* msgb);
+void fwp_msgb_reset_data(struct fwp_msgb* msgb);
+unsigned char* fwp_msgb_shift(struct fwp_msgb* msgb, unsigned int len);
+void fwp_msgb_reserve(fwp_msgb_t *msgb, unsigned int len);
+
+/*struct fwp_socketaddr* fwp_socket_create(struct sockaddr *_addr, socklen_t _addrlen);
+inline void fwp_socket_set(struct fwp_socketaddr *fwpsock, struct sockaddr *_addr, 
+                                 socklen_t _addrlen);
+*/
+#endif /* _FWP_MSGB_H */
diff --git a/src/fwp/fwp/lib/fwp/fwp_msgq.c b/src/fwp/fwp/lib/fwp/fwp_msgq.c
new file mode 100644 (file)
index 0000000..1af89bd
--- /dev/null
@@ -0,0 +1,167 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#include "fwp_msgq.h"
+#include <errno.h>
+
+/**
+ *Initialize message queue 
+ *@param[in] msgq Message queue
+ **/
+void fwp_msgq_init(struct fwp_msgq *msgq)
+{
+       msgq->nr_pending = 0;
+       msgq->in = 0;
+       msgq->out = 0;
+       pthread_mutex_init(&msgq->lock, NULL); /* fast mutex */
+       sem_init(&msgq->msg_sem, 0, 0);
+}
+
+/**
+ * Enqueue message in message queue
+ *
+ * @param[in] msgq Message queue
+ *`@param[in] msgb Message buffer which stores a message
+ * @return
+ *   Zero on success, -1 or error.
+ **/
+int fwp_msgq_enqueue(struct fwp_msgq *msgq, struct fwp_msgb *msgb)
+{
+       /* acquire queue mutex */
+       pthread_mutex_lock(&msgq->lock);
+       
+       if (!(msgq->nr_pending < FWP_MSGQ_SIZE)){
+               /*if (msgq->qr_policy == NEWCOMER) {*/  
+               
+               /*release queue mutex*/
+               pthread_mutex_unlock(&msgq->lock);
+               errno = ENOBUFS;
+               return -1;
+               /* }
+                * if (msgq->qr_policy == OLDEST)
+                       msgq->first = (msgq->first++) % FWP_MSGQ_SIZE;
+                       msgq->nr_pending--;
+               */
+       }
+
+       /* depends on queuing policy specifies in endpoint */
+       msgq->queue[msgq->in] = msgb;
+       msgq->nr_pending++;
+       msgq->in = (++msgq->in) & (FWP_MSGQ_SIZE - 1);
+
+       sem_post(&msgq->msg_sem);
+       /* release queue mutex */
+       pthread_mutex_unlock(&msgq->lock);
+
+       return 0;
+}
+
+/**
+ * Dequeue message from message queue
+ *
+ * @param[in] msgq Message queue
+ * @return
+ *   NULL if message queue in empty 
+ *   else returns pointer to message buffer(msgb) 
+ **/
+struct fwp_msgb* fwp_msgq_dequeue(struct fwp_msgq *msgq)
+{
+       struct fwp_msgb* msgb;
+       
+       sem_wait(&msgq->msg_sem);
+       /* acquire queue mutex */
+       pthread_mutex_lock(&msgq->lock);
+       
+       msgb = msgq->queue[msgq->out];
+       msgq->nr_pending--;
+       msgq->out = (++msgq->out) & (FWP_MSGQ_SIZE - 1);
+       
+       /* release queue mutex */
+       pthread_mutex_unlock(&msgq->lock);
+
+       return msgb;
+} 
+
+struct fwp_msgb* fwp_msgq_peek(struct fwp_msgq *msgq)
+{
+       struct fwp_msgb* msgb;
+       
+       pthread_mutex_lock(&msgq->lock);
+
+       if (msgq->nr_pending > 0)
+               msgb = msgq->queue[msgq->out];
+       else
+               msgb = NULL;
+       pthread_mutex_unlock(&msgq->lock);
+
+       return msgb;
+} 
+
+/*
+ * Dequeue all messages from message queue
+ *
+ * @param[in] msgq Message queue
+ * @return
+ *   NULL if message queue is empty
+ *   else returns pointer to message buffer(msgb) 
+ **/
+void fwp_msgq_dequeue_all(struct fwp_msgq *msgq)
+{
+       struct fwp_msgb *msgb;
+
+       /* acquire queue mutex */
+       pthread_mutex_lock(&msgq->lock);
+       
+       while (msgq->in != msgq->out){
+               msgb = msgq->queue[msgq->out];
+               msgq->nr_pending--;
+               msgq->out = (++msgq->out) & (FWP_MSGQ_SIZE - 1);
+               fwp_msgb_free(msgb);
+       }
+       
+       sem_init(&msgq->msg_sem, 0, 0);
+       /* release queue mutex */
+       pthread_mutex_unlock(&msgq->lock);
+}
diff --git a/src/fwp/fwp/lib/fwp/fwp_msgq.h b/src/fwp/fwp/lib/fwp/fwp_msgq.h
new file mode 100644 (file)
index 0000000..d30a048
--- /dev/null
@@ -0,0 +1,81 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#ifndef _FWP_MSGQ_H
+#define _FWP_MSGQ_H
+
+#include "fwp_conf.h"
+#include "fwp_msgb.h"
+
+#include <pthread.h>
+#include <semaphore.h>
+
+/**
+ * Message queue structure
+ *
+ */
+struct fwp_msgq {
+       unsigned int    nr_pending;  /**< number of messages in the queue */
+       struct fwp_msgb* queue[FWP_MSGQ_SIZE];
+       unsigned int    in;   /**< add at offset (in % size) */ 
+       unsigned int    out;  /**< extracted from offset (out % size) */ 
+       pthread_mutex_t  lock; /**< queue lock */
+       sem_t   msg_sem;     /**< semaphore to block on empty mqueue */
+       
+       /* queue reject policy */
+       /*queue_rejection_policy qr_policy;*/
+};
+
+void fwp_msgq_init(struct fwp_msgq *msgq);
+
+int fwp_msgq_enqueue(struct fwp_msgq *msgq, struct fwp_msgb* msgb);
+
+struct fwp_msgb* fwp_msgq_dequeue(struct fwp_msgq *msgq);
+struct fwp_msgb* fwp_msgq_peek(struct fwp_msgq *msgq);
+void fwp_msgq_dequeue_all(struct fwp_msgq *msgq);
+
+/* void fwp_msgq_setpolicy */
+
+#endif /* _FWP_MSGQ_H */
diff --git a/src/fwp/fwp/lib/fwp/fwp_types.h b/src/fwp/fwp/lib/fwp/fwp_types.h
new file mode 100644 (file)
index 0000000..bf81e13
--- /dev/null
@@ -0,0 +1,53 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#ifndef _FWP_TYPES 
+#define _FWP_TYPES
+
+/* Flags values */
+#define FWP_RELIABLE   1
+#define FWP_BEST_EFFORT 2
+
+#endif /* _FWP_TYPES */
diff --git a/src/fwp/fwp/lib/fwp/fwp_utils.c b/src/fwp/fwp/lib/fwp/fwp_utils.c
new file mode 100644 (file)
index 0000000..69cf356
--- /dev/null
@@ -0,0 +1,198 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#include "fwp_utils.h"
+
+#include <unistd.h>
+#include <sched.h>
+/*#include <stdlib.h>*/
+#include "fwp_debug.h"
+#include <errno.h>
+
+/*const int prio_to_ac[8] = {2,3,3,2,1,1,0,0};
+const unsigned int ac_to_tos[4] = {224,160,96,64};
+const char *ac_to_text[4] = {[AC_VO] = "AC_VO", [AC_VI] = "AC_VI", 
+                            [AC_BE] = "AC_BE", [AC_BK] = "AC_BK", };
+*/
+
+void fwp_timespec_add (struct timespec *sum, const struct timespec *left,
+             const struct timespec *right)
+{
+       sum->tv_sec = left->tv_sec + right->tv_sec;
+       sum->tv_nsec = left->tv_nsec + right->tv_nsec;
+
+       if (sum->tv_nsec >= 1000000000){
+               ++sum->tv_sec;
+               sum->tv_nsec -= 1000000000;
+       }
+}
+
+void fwp_timespec_sub (struct timespec *diff, const struct timespec *left,
+             const struct timespec *right)
+{
+       diff->tv_sec = left->tv_sec - right->tv_sec;
+       diff->tv_nsec = left->tv_nsec - right->tv_nsec;
+
+       if (diff->tv_nsec < 0){
+                 --diff->tv_sec;
+                 diff->tv_nsec += 1000000000;
+       }
+}
+
+void fwp_timespec_modulo(struct timespec *remainder, struct timespec *dividend, 
+                               struct timespec *dividor)
+{
+       long long a, b, res;
+
+       a = dividend->tv_sec * SEC_TO_USEC + dividend->tv_nsec / USEC_TO_NSEC;
+       b = dividor->tv_sec * SEC_TO_USEC + dividor->tv_nsec / USEC_TO_NSEC;
+       res = a % b;
+       remainder->tv_sec = res / SEC_TO_USEC;
+       remainder->tv_nsec = ( res % SEC_TO_USEC ) * USEC_TO_NSEC;
+}
+
+int fwp_set_rt_prio(int priority)
+{
+       int maxpri, minpri;
+       static struct sched_param param;
+
+       if ((maxpri = sched_get_priority_max(SCHED_FIFO)) == -1) {
+               FWP_ERROR("sched_get_priority_max call failed: %s\n", 
+                               strerror(errno));
+               return -1;
+       }       
+
+       if ((minpri = sched_get_priority_min(SCHED_FIFO)) == -1) {
+               FWP_ERROR("sched_get_priority_min call failed: %s\n", 
+                               strerror(errno));
+               return -1;
+       }
+
+       if (priority > maxpri)  {
+               FWP_ERROR("parameter %d is greater than the maximal allowed"
+                               " priority %d.\n", priority, maxpri);
+               errno = EINVAL;
+               return -1;
+       }
+
+       if (priority < minpri)  {
+               FWP_ERROR("priority parameter %d is lower than the minimal "
+                               "allowed priority %d.\n", priority, minpri);
+               errno = EINVAL;
+               return -1;
+       }
+
+       param.sched_priority = priority;
+
+       if (sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
+               /*FWP_ERROR("sched_setscheduler call failed: %s\n", 
+                               strerror(errno));*/
+               return -1;
+       }
+
+       return 0;
+}
+
+int fwp_create_unix_socket(char *path, struct sockaddr_un *addr)
+{
+       int sockfd;
+
+       if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1){
+               FWP_ERROR("socket error: %s", strerror(errno));
+               return (-1);
+       }
+       
+       bzero(addr, sizeof(addr));
+       addr->sun_family = AF_UNIX;
+       strcpy(addr->sun_path, path);
+       
+       unlink(path);
+
+       if (bind(sockfd, (struct sockaddr*)addr, 
+                sizeof(*addr)) == -1) {
+                       FWP_ERROR("fwp_open_unix_socket - bind error: %s", strerror(errno));
+                       return (-1);
+       }
+       
+       return sockfd;  
+}
+
+int fwp_create_inet_socket(unsigned int port, struct sockaddr_in *addr)
+{
+       int sockfd;
+
+       if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
+               FWP_ERROR("socket error: %s", strerror(errno));
+               return (-1);
+       }
+       
+       addr->sin_family = AF_INET;
+        addr->sin_addr.s_addr = INADDR_ANY;
+       addr->sin_port = htons(port);
+               
+       if (bind(sockfd, (struct sockaddr*)addr, 
+                sizeof(*addr)) == -1) {
+                       
+               FWP_ERROR("bind error: %s", strerror(errno));
+               return (-1);
+       }
+       
+       return sockfd;  
+}
+
+/*void block_signals(void)
+{
+       sigset_t sigset;
+       int ret;
+       sigemptyset(&sigset);
+       sigaddset(&sigset, SIGINT);
+       sigaddset(&sigset, SIGTERM);
+       ret = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+       if (ret != 0) {
+               FWP_ERROR("pthread_sigmask failed: %s", strerror(errno));
+               exit(1);
+       }
+}
+*/
diff --git a/src/fwp/fwp/lib/fwp/fwp_utils.h b/src/fwp/fwp/lib/fwp/fwp_utils.h
new file mode 100644 (file)
index 0000000..5020ec5
--- /dev/null
@@ -0,0 +1,77 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#ifndef _FWP_UTILS_H
+#define _FWP_UTILS_H
+
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <fwp_msgb.h>
+
+#define Kbit 1000
+#define Mbit (Kbit*Kbit)
+
+#define SEC_TO_NSEC       1000000000LL
+#define SEC_TO_USEC       1000000LL
+#define MSEC_TO_USEC      1000LL
+#define USEC_TO_NSEC      1000LL
+
+/*extern const int prio_to_ac[8];
+extern const unsigned int ac_to_tos[4];
+extern const char *ac_to_text[4];
+*/
+
+void fwp_timespec_add (struct timespec *sum, const struct timespec *left, 
+                               const struct timespec *right);
+void fwp_timespec_sub (struct timespec *diff, const struct timespec *left,
+                               const struct timespec *right);
+void fwp_timespec_modulo(struct timespec *dividend, struct timespec *dividor,
+                               struct timespec *remainder);
+
+int fwp_set_rt_prio(int priority);
+int fwp_create_unix_socket(char *path, struct sockaddr_un *addr);
+int fwp_create_inet_socket(unsigned int port, struct sockaddr_in *addr);
+
+#endif /* _FWP_UTILS_H */
diff --git a/src/fwp/fwp/lib/fwp/fwp_vres.c b/src/fwp/fwp/lib/fwp/fwp_vres.c
new file mode 100644 (file)
index 0000000..1078bd1
--- /dev/null
@@ -0,0 +1,499 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2009 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+
+#include "fwp_utils.h"
+#include "fwp_vres.h"
+
+#include "fwp_msgq.h"
+#include "fwp_endpoint.h"
+#include "fwp_debug.h"
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+static void* fwp_vres_tx_thread(void *_vres);
+
+typedef enum {
+       UNTOUCHED,
+       CHANGED,
+       QUEUED,
+} fwp_vres_flag_t;
+
+fwp_vres_params_t fwp_vres_params_default = {
+       .ac_id = FWP_AC_VO,
+        .budget = 100,
+       .period = {.tv_sec = 2 , .tv_nsec = 111111},
+       .src = { 0 },
+};
+
+/**
+ * Structure of FWP vres.
+ * Internal representation of vres
+ * 
+ */
+struct fwp_vres{
+       struct fwp_vres_params          params;
+       fwp_vres_flag_t                 flags;
+       pthread_mutex_t                 mutex;
+       pthread_cond_t                  cond; /**< Signalizes budget replenishment */
+       fwp_budget_t                    budget; /**< Current remaining budget */
+       fwp_period_t                    period; /**< Period for this "activation" */
+       struct timespec                 replenish_at; /**< Time of next replenishment */
+       sem_t                           consumed;
+       /**< endpoint bounded to this vres */
+       struct fwp_endpoint             *epoint;
+       pthread_t                       tx_thread; /**< tx_thread id*/
+       pthread_attr_t                  tx_thread_attr;
+       /** Copy of bound enpoint's socket - used for future changes
+        * of vres parameters. */
+       int                             ac_sockd;
+       /** Queue for messages to send */
+       struct fwp_msgq                 msg_queue;
+       /** If true, it is always allowed to send messages through this vres. */
+       bool                            bypass;
+};
+
+/**< mapping priority to ac*/
+static const int prio_to_ac[8] = {2,3,3,2,1,1,0,0};
+/**< IP tos for AC_VI, AC_VO, AC_BE, AC_BK */ 
+static const unsigned int ac_to_tos[4] = {224,160,96,64};
+
+/**
+ * Set access category (AC) to socket
+ *
+ * \param[in] sockd Socket descriptor
+ * \param[in] ac_id AC identifier
+ * 
+ * \return On success returns zero. 
+ * On error, negative error code is returned. 
+ *
+ */
+static inline int fwp_vres_set_ac(int sockd, fwp_ac_t ac_id) 
+{
+       unsigned int tos;
+       
+       tos = ac_to_tos[ac_id];
+       if (setsockopt(sockd, SOL_IP, IP_TOS, &tos, sizeof(tos)) == -1) {
+               FWP_ERROR("setsockopt: %s", strerror(errno));
+               return (-1);
+       }
+       
+       return 0;
+}
+
+static inline void set_flag(fwp_vres_t *vres, fwp_vres_flag_t flag)
+{
+       vres->flags |= (1 << flag);
+}
+
+static inline void clear_flag(fwp_vres_t *vres, fwp_vres_flag_t flag)
+{
+       vres->flags &= ~(1 << flag);
+}
+
+static inline int get_flag(fwp_vres_t *vres, fwp_vres_flag_t flag)
+{
+       return !!(vres->flags & (1 << flag));
+}
+
+static inline void clear_all_flags(fwp_vres_t *vres)
+{
+       vres->flags = 0;
+}
+
+static inline void fwp_vres_free(fwp_vres_t *vres)
+{
+       free(vres);
+}
+
+/*inline int fwp_vres_get(fwp_vres_id_t vres_id, fwp_vres_t **vres )
+{
+       if ((vres_id < 0) || (vres_id > fwp_vres_table.nr_vres - 1))
+               return -EINVAL;
+       *vres = &fwp_vres_table.entry[vres_id];
+       return 0;
+}
+*/
+
+/**
+ * Allocate vres
+ *
+ * \return On success returns vres descriptor. 
+ */
+fwp_vres_t *fwp_vres_alloc()
+{
+       fwp_vres_t *vres = malloc(sizeof(*vres));
+       if (vres) {
+               memset(vres, 0, sizeof(*vres));
+               FWP_DEBUG("Allocated vres\n");
+       }
+       return vres;
+}
+
+static int apply_params(fwp_vres_t *vres)
+{
+       int rv = 0;
+       vres->period = vres->params.period;
+       vres->budget = vres->params.budget;
+       set_flag(vres, UNTOUCHED);
+       if (get_flag(vres, CHANGED)) {
+               clear_flag(vres, CHANGED);
+               rv = fwp_vres_set_ac(vres->ac_sockd, vres->params.ac_id);
+       }
+       return rv;
+}
+
+/**
+ * Set vres params
+ *
+ * \param[in] vresp Vres descriptor
+ * \param[in] params Vres parameters
+ *
+ * \return On success returns zero. 
+ * On error, negative error code is returned. 
+ *
+ */
+int fwp_vres_set_params(fwp_vres_t *vres, fwp_vres_params_t *params)
+{
+       int rv = 0;
+
+       if (!vres) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       pthread_mutex_lock(&vres->mutex);
+
+       if (vres->epoint &&
+           params->src.s_addr != vres->params.src.s_addr) {
+               errno = EREMCHG;
+               rv = -1;
+               goto out;
+       }
+       vres->params = *params;
+       if (vres->epoint) {
+               set_flag(vres, CHANGED);
+               if (get_flag(vres, UNTOUCHED))
+                       rv = apply_params(vres);
+       }
+out:
+       pthread_mutex_unlock(&vres->mutex);
+       return rv;
+}
+
+/**
+ * Creates new vres
+ *
+ * \param[in] params Vres parameters
+ * \param[out] vresp Pointer to the descriptor of newly created vres
+ *
+ * \return Zero on success, -1 on error and errno is set
+ * appropriately.
+ */
+int fwp_vres_create(fwp_vres_params_t *params, fwp_vres_t **vresp)
+{
+       int rv;
+       fwp_vres_t *vres;
+       
+       vres = fwp_vres_alloc();
+       if (!vres) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       pthread_mutexattr_t ma;
+       rv = pthread_mutexattr_init(&ma);
+       rv = pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_INHERIT);
+       if (rv) return rv;
+       pthread_mutex_init(&vres->mutex, &ma);
+       pthread_cond_init(&vres->cond, NULL);
+       
+       vres->params = *params;
+       apply_params(vres);
+       fwp_msgq_init(&vres->msg_queue);
+
+       if (getenv("FWP_BYPASS"))
+               vres->bypass = true;
+
+       pthread_attr_init(&vres->tx_thread_attr);
+       if ((rv = pthread_create(&vres->tx_thread, &vres->tx_thread_attr, 
+                           fwp_vres_tx_thread, (void*) vres)) != 0){
+               goto err;
+       }
+
+       *vresp = vres;
+       
+       return 0;
+err:   
+       fwp_msgq_dequeue_all(&vres->msg_queue);
+       fwp_vres_free(vres);
+       return -1; 
+}
+
+/**
+ * Destroys vres
+ *
+ * \param[in] vres Vres descriptor
+ *
+ * \return Zero on success, -1 on error and errno is set
+ * appropriately.
+ */
+int fwp_vres_destroy(fwp_vres_t *vres)
+{      
+       if (!vres) {
+               errno = EINVAL;
+               return -1;
+       }
+       
+       pthread_cancel(vres->tx_thread);
+       pthread_cond_destroy(&vres->cond);
+       pthread_mutex_destroy(&vres->mutex);
+               
+       fwp_msgq_dequeue_all(&vres->msg_queue);
+       fwp_vres_free(vres);
+       
+       FWP_DEBUG("Vres destroyed.\n");
+       return  0;
+}
+
+static void do_consume_budget(struct fwp_vres *vres, size_t size)
+{
+       if (get_flag(vres, UNTOUCHED)) {
+               /* Setup next replenish time */
+               struct timespec now;
+               clear_flag(vres, UNTOUCHED);
+               if (get_flag(vres, QUEUED))
+                       now = vres->replenish_at;
+               else
+                       clock_gettime(CLOCK_MONOTONIC, &now);
+               fwp_timespec_add(&vres->replenish_at, &now, &vres->period);
+               sem_post(&vres->consumed);
+       }
+       vres->budget -= size;
+}
+
+int __consume_budget(struct fwp_vres *vres, size_t size, bool can_block)
+{
+       int ret = 0;
+       if (vres->bypass)
+               return 0;
+       if (vres->params.budget < size) {
+               errno = ENOSR;
+               return -1;
+       }
+       while (can_block && vres->budget < size) {
+               ret = pthread_cond_wait(&vres->cond, &vres->mutex);
+               /* The budget might have been changed while we were
+                * waiting, so check it again. */
+               if (vres->params.budget < size) {
+                       errno = ENOSR;
+                       return -1;
+               }
+       }
+       if (ret == 0) {
+               if (vres->budget >= size) {
+                       do_consume_budget(vres, size);
+                       ret = 0;
+               } else {
+                       set_flag(vres, QUEUED);
+                       ret = 1;
+               }
+       }
+       return ret;
+}
+
+/** 
+ * Tries to consume (a part of) budget
+ * 
+ * @param vres VRES whose budget is conumed.
+ * @param size How much to consume (in bytes).
+ * @param can_block True, indicates that the function can block to
+ * wait for budget replenishment. False causes no blocking and if 1 is
+ * returned, the calles must call fwp_vres_enqueue() to enqueue the
+ * packet to be sent later after replenishing.
+ * 
+ * @return Zero if budget was consumed, 1 if there is not enough
+ * budget available and blocking was not allowed, -1 in case of error.
+ */
+int fwp_vres_consume_budget(struct fwp_vres *vres, size_t size, bool can_block)
+{
+       int ret = 0;
+       pthread_mutex_lock(&vres->mutex);
+       ret = __consume_budget(vres, size, can_block);
+       pthread_mutex_unlock(&vres->mutex);
+       return ret;
+}
+
+int fwp_vres_enqueue(struct fwp_vres *vres, struct fwp_endpoint *ep,
+                    const void *msg, size_t size)
+{
+       struct fwp_msgb *msgb;
+       int ret;
+       
+       if (!(msgb = fwp_msgb_alloc(size)))
+               return -1;
+       memcpy(msgb->data, msg, size);
+       fwp_msgb_put(msgb, size);
+       ret = fwp_msgq_enqueue(&vres->msg_queue, msgb);
+       if (ret) {
+               fwp_msgb_free(msgb);
+               return ret;
+       }
+       return ret;
+}
+
+static void wait_for_replenish(struct fwp_vres *vres)
+{
+       sem_wait(&vres->consumed);
+       clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
+                       &vres->replenish_at, NULL);
+}
+
+static void send_queue(struct fwp_vres *vres)
+{
+       struct fwp_msgb *msgb;
+       bool can_send;
+       msgb = fwp_msgq_dequeue(&vres->msg_queue);
+       can_send = (0 == __consume_budget(vres, msgb->len, false));
+       if (!can_send) {
+               fwp_msgb_free(msgb);
+               FWP_ERROR("Cannot send queued packet (budget decreased?)\n");
+               return;
+       }
+       /* If we cannot send the whole queue, the flag will be set
+        * later by __consume_budget(). */
+       clear_flag(vres, QUEUED);
+
+       while (msgb) {
+               fwp_endpoint_do_send(vres->epoint, msgb->data, msgb->len);
+               fwp_msgb_free(msgb);
+               msgb = fwp_msgq_peek(&vres->msg_queue);
+               if (msgb) {
+                       can_send = (0 == __consume_budget(vres, msgb->len, false));
+                       if (can_send) {
+                               msgb = fwp_msgq_dequeue(&vres->msg_queue);
+                       } else {
+                               msgb = NULL;
+                               return;
+                       }
+               }
+       }
+}
+
+static void replenish(struct fwp_vres *vres)
+{
+       pthread_mutex_lock(&vres->mutex);
+       apply_params(vres);
+       if (get_flag(vres, QUEUED))
+               send_queue(vres);
+       pthread_cond_broadcast(&vres->cond);
+       pthread_mutex_unlock(&vres->mutex);
+}
+
+/**
+ * Thread that does budgeting
+ *
+ */
+static void* fwp_vres_tx_thread(void *_vres)
+{
+       struct fwp_vres *vres = (struct fwp_vres*)_vres;
+       unsigned int    ac_id = vres->params.ac_id;
+
+       fwp_set_rt_prio(90 - ac_id);
+       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+       pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);   
+       
+       while (1) {
+               wait_for_replenish(vres);
+               pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+               replenish(vres);
+               pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+       }
+
+       return NULL;
+}
+
+/*int fwp_vres_bind(fwp_vres_t *vres, struct fwp_endpoint *epoint)*/
+int fwp_vres_bind(fwp_vres_t *vres, struct fwp_endpoint *ep, int sockd, struct in_addr  *src)
+{
+       int rv = 0;
+
+       if (!vres) {
+               errno = EINVAL;
+               rv = -1;
+               goto err;
+       }
+       
+       if (vres->epoint) { /*if already bounded */
+               errno = EBUSY;
+               rv = -1;
+               goto err;
+       }
+
+       vres->ac_sockd = sockd;
+       *src = vres->params.src;
+       rv = fwp_vres_set_ac(vres->ac_sockd, vres->params.ac_id);
+       if (rv)
+               goto err;
+       vres->epoint = ep;
+err:
+       return rv;
+}
+
+int fwp_vres_unbind(fwp_vres_t *vres)
+{
+       if (!vres) {
+               errno = EINVAL;
+               return -1;
+       }
+       pthread_mutex_lock(&vres->mutex);
+       vres->epoint = NULL;
+       pthread_mutex_unlock(&vres->mutex);
+       /* TODO: consider what to do with pending messages */
+       fwp_msgq_dequeue_all(&vres->msg_queue);
+       return 0;
+}
diff --git a/src/fwp/fwp/lib/fwp/fwp_vres.h b/src/fwp/fwp/lib/fwp/fwp_vres.h
new file mode 100644 (file)
index 0000000..c0bf84c
--- /dev/null
@@ -0,0 +1,103 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#ifndef _FWP_VRES_H
+#define _FWP_VRES_H
+
+#include <netinet/in.h>
+#include <stdbool.h>
+
+struct fwp_vres;
+typedef struct fwp_vres fwp_vres_t;
+
+/** WMM defines 4 queues */
+typedef enum  {
+       FWP_AC_VO = 0,
+       FWP_AC_VI = 1,
+       FWP_AC_BE = 2,
+       FWP_AC_BK = 3
+} fwp_ac_t;
+
+fwp_ac_t fwp_vres_get_ac(fwp_vres_t *vres);
+
+
+#ifdef _FWP_INTERNALS_
+
+#include "fwp_msgb.h"
+
+typedef unsigned int fwp_vres_id_t;
+typedef unsigned int fwp_vparam_id_t;
+typedef unsigned long int fwp_budget_t;
+typedef struct timespec  fwp_period_t;
+
+/**
+ * FWP vres parameters 
+ * 
+ */
+typedef
+struct fwp_vres_params {
+       fwp_budget_t    budget;         /**< bytes per period */
+       /** all time units are in microseconds */       
+       fwp_period_t    period; 
+       fwp_ac_t        ac_id;          /**< AC id ~ priority of vres */
+       struct in_addr  src;
+} fwp_vres_params_t;
+
+fwp_vres_t *fwp_vres_alloc();
+int fwp_vres_set_params(fwp_vres_t *vres, fwp_vres_params_t *params);
+int fwp_vres_create(fwp_vres_params_t *params, fwp_vres_t **vresp);
+int fwp_vres_destroy(fwp_vres_t *vres);
+
+int fwp_vres_consume_budget(struct fwp_vres *vres, size_t size, bool can_block);
+struct fwp_endpoint;
+int fwp_vres_enqueue(struct fwp_vres *vres, struct fwp_endpoint *ep,
+                    const void *msg, size_t size);
+int fwp_vres_bind(fwp_vres_t *vres, struct fwp_endpoint *ep, int sockd, struct in_addr *src);
+int fwp_vres_unbind(fwp_vres_t *vres);
+
+extern fwp_vres_params_t fwp_vres_params_default;
+
+#endif /* _FWP_INTERNALS_ */
+#endif /* _FWP_VRES_H */
diff --git a/src/fwp/fwp/lib/fwp/tests/Makefile b/src/fwp/fwp/lib/fwp/tests/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/lib/fwp/tests/Makefile.omk b/src/fwp/fwp/lib/fwp/tests/Makefile.omk
new file mode 100644 (file)
index 0000000..23147ae
--- /dev/null
@@ -0,0 +1,4 @@
+SUBDIRS= fwp_msgtest fwp_vrestest fwp_prototest 
+#fwp_prototest fwp_mngrtest  
+#SUBDIRS= fwp_msgtest fwp_vrestest fwp_prototest fwp_mngrtest  
+#fwp_mngrtest unixsocktest
diff --git a/src/fwp/fwp/lib/fwp/tests/fwp_msgtest/Makefile b/src/fwp/fwp/lib/fwp/tests/fwp_msgtest/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/lib/fwp/tests/fwp_msgtest/Makefile.omk b/src/fwp/fwp/lib/fwp/tests/fwp_msgtest/Makefile.omk
new file mode 100644 (file)
index 0000000..92cb304
--- /dev/null
@@ -0,0 +1,4 @@
+test_PROGRAMS = fwp_msgtest
+CFLAGS+= -D_FWP_INTERNALS_
+fwp_msgtest_SOURCES+= fwp_msgtest.c
+lib_LOADLIBES += pthread rt fwp 
diff --git a/src/fwp/fwp/lib/fwp/tests/fwp_msgtest/fwp_msgtest.c b/src/fwp/fwp/lib/fwp/tests/fwp_msgtest/fwp_msgtest.c
new file mode 100644 (file)
index 0000000..ff1877c
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * \file fwp_msgtest.c
+ *
+ * This is a test application for msg handling that
+ * - allocates two msgb
+ * - serializes two contracts into msgb
+ * - put both msgb to message queue
+ * - revert previous steps 
+ * - compare contracts 
+ */
+#include "fwp_msgq.h"
+#include "fwp_msgb.h"
+
+#include <semaphore.h>
+#include <stdio.h>
+
+int main(int argc, char** argv)
+{
+       struct fwp_msgq msgq;
+       struct fwp_msgb *msgb;
+       int val_w1 = 1;
+       int val_w2 = 2;
+       int val_r1, val_r2;
+       int nparams;
+
+       nparams = argc;
+       fwp_msgq_init(&msgq);   
+       printf("in=%d out=%d pending=%d \n",msgq.in,msgq.out,msgq.nr_pending);
+       
+       /* prepare and enqueue the first message buffer */
+       msgb = fwp_msgb_alloc(sizeof(val_w1));
+       if (!msgb) {
+               printf("Could not allocate msgb for message A\n");
+               return -1;
+       }else 
+               printf("Message buffer for message A allocated\n");
+
+       memcpy(msgb->data, &val_w1, sizeof(val_w1)); 
+       printf("Enqueue message A. ");
+       if (!fwp_msgq_enqueue(&msgq, msgb))
+               printf("OK.\n");
+       else {
+               printf("Failed! \n");
+               return -1;
+       }
+       
+       printf("in=%d out=%d pending=%d \n",msgq.in,msgq.out,msgq.nr_pending);
+       /* prepare and enqueue the second message buffer */
+       msgb = fwp_msgb_alloc(sizeof(val_w2));
+       if (!msgb) {
+               printf("Could not allocate msgb for message B\n");
+               return -1;
+       }else 
+               printf("Message buffer for message B allocated\n");
+
+       memcpy(msgb->data, &val_w2, sizeof(val_w2)); 
+       printf("Enqueue message B. ");
+       if (!fwp_msgq_enqueue(&msgq, msgb))
+               printf("OK.\n");
+       else {
+               printf("Failed! \n");
+               return -1;
+       }
+       
+       printf("in=%d out=%d pending=%d \n",msgq.in,msgq.out,msgq.nr_pending);
+       
+       /* dequeue the first message and compare with original contract*/
+       printf("Dequeue message A. ");
+       msgb = fwp_msgq_dequeue(&msgq);
+       if (!msgb) {
+               printf("Failed! \n");
+               return -1;
+       }else
+               printf("OK.\n");
+
+       printf("in=%d out=%d pending=%d \n",msgq.in,msgq.out,msgq.nr_pending);
+       
+       memcpy(&val_r1, msgb->data, sizeof(val_w1)); 
+       fwp_msgb_free(msgb);
+       
+       if (val_w1 != val_r1) {
+               printf("Message A: W/R values do not match.\n");
+               return -1;
+       }
+       printf("Message A: W/R values matches.\n");
+       
+
+       /* dequeue the second message and compare with original contract*/
+       printf("Dequeue message B. ");
+       msgb = fwp_msgq_dequeue(&msgq);
+       if (!msgb) {
+               printf("Failed! \n");
+               return -1;
+       }else
+               printf("OK.\n");
+
+       printf("in=%d out=%d pending=%d \n",msgq.in,msgq.out,msgq.nr_pending);
+       
+       memcpy(&val_r2, msgb->data, sizeof(val_w2)); 
+       fwp_msgb_free(msgb);
+       
+       if (val_w2 != val_r2) {
+               printf("Message B: W/R values do not match.\n");
+               return -1;
+       }
+       printf("Message B: W/R values matches.\n");
+
+       msgb = fwp_msgq_dequeue(&msgq);
+
+       if (msgb) {
+               printf("Message should be empty but is is not\n");
+               return -1;
+       }
+               
+       printf("%s PASSED!\n", argv[0]);
+       return 0;
+}
diff --git a/src/fwp/fwp/lib/fwp/tests/fwp_prototest/Makefile b/src/fwp/fwp/lib/fwp/tests/fwp_prototest/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/lib/fwp/tests/fwp_prototest/Makefile.omk b/src/fwp/fwp/lib/fwp/tests/fwp_prototest/Makefile.omk
new file mode 100644 (file)
index 0000000..23c0801
--- /dev/null
@@ -0,0 +1,5 @@
+test_PROGRAMS = fwp_sendrecv_test1 fwp_sendrecv_test2
+CFLAGS+= -D_FWP_INTERNALS_
+fwp_sendrecv_test1_SOURCES+= fwp_sendrecv_test1.c
+fwp_sendrecv_test2_SOURCES+= fwp_sendrecv_test2.c
+lib_LOADLIBES += fwp pthread rt ulut 
diff --git a/src/fwp/fwp/lib/fwp/tests/fwp_prototest/fwp_sendrecv_test1.c b/src/fwp/fwp/lib/fwp/tests/fwp_prototest/fwp_sendrecv_test1.c
new file mode 100644 (file)
index 0000000..ff7f062
--- /dev/null
@@ -0,0 +1,114 @@
+/**
+ * \file fwp_sendrecv_test1.c  
+ *
+ * This a test application that:
+ * - creates two vres without negotiation
+ * - creates send and receive endpoint 
+ * - binds that endpoint to vres
+ * - sends two messages
+ * - receives messages
+ * - destroys vres
+ *
+ */
+#define CONFIGURE_FWP_MNGT 0
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+
+int main()
+{
+//     struct sockaddr_in local_addr, rem_addr, from;
+        ssize_t len;
+       fwp_vres_t *vres1, *vres2;
+       int i;
+       struct fwp_vres_params vparam1, vparam2;
+       char msg1[] = "Hello1";
+       char msg2[] = "Hello2";
+       char buffer[30];
+       struct fwp_endpoint *sepoint1, *sepoint2, *repoint1, *repoint2;
+       fwp_endpoint_attr_t attr;
+       fwp_addr_t from;
+       
+       fwp_endpoint_attr_init(&attr);
+
+       vparam1.ac_id = FWP_AC_VO; 
+       vparam1.budget = 100;
+       vparam1.period.tv_sec = 2; 
+       vparam1.period.tv_nsec = 0; 
+
+       vparam2.ac_id = FWP_AC_BK; 
+       vparam2.budget = 100;
+       vparam2.period.tv_sec = 0;
+       vparam2.period.tv_nsec = 100000;
+
+       printf("Start\n");
+       fwp_init();
+       
+       printf("Create vres1, vres2\n");
+       if (fwp_vres_create(&vparam1, &vres1) < 0) {
+               printf("Unable to create vres1\n");
+               return -1;
+       }
+       printf("Vres1 created \n");
+       
+       if (fwp_vres_create(&vparam2, &vres2) < 0){
+               fprintf(stderr,"Unable to create vres2\n");
+               return -1;
+       }
+       printf("Vres2 created\n");
+       
+       /* local_addr should be handled when creating socket */
+       if (fwp_receive_endpoint_create(7777, &attr,&repoint1) < 0){
+               return -1;
+       }
+       printf("Receive endpoint created\n");
+       
+       if (fwp_receive_endpoint_create(7778, &attr,&repoint2) < 0){
+               return -1;
+       }
+       printf("Receive endpoint created\n");
+       
+       if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), 7777, 0, 
+                                       &sepoint1) < 0) {
+               return -1;
+       }
+       printf("Send endpoint 1 created\n");
+       fwp_send_endpoint_bind(sepoint1, vres1);
+       
+       if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), 7778, 0, 
+                                       &sepoint2) < 0){
+               return -1;
+       }
+       printf("Send endpoint 2 created\n");
+       fwp_send_endpoint_bind(sepoint2, vres2);
+       
+       fwp_send_sync(sepoint1, msg1, sizeof(msg1));
+       fwp_send_sync(sepoint1, msg2, sizeof(msg2));
+
+       for (i = 0; i < 2; i++) {
+               if ((len = fwp_recv(repoint1, buffer, sizeof(buffer), &from, 
+                       0)) < 0) {
+                       perror("Error while receiving data");
+                       return -1;
+               } 
+                       else printf("Received - %s\n", buffer);
+       }
+
+       if (fwp_vres_destroy(vres1) < 0) {
+               perror("Unable to destroy vres1\n");
+               return -1;
+       }
+       printf("Vres1 destroyed\n");
+       
+       if (fwp_vres_destroy(vres2) < 0){
+               perror("Unable to destroy vres2\n");
+               return -1;
+       }       
+       printf("Vres2 destroyed\n");
+
+       printf("Test PASSED!\n");
+       return 0;
+}
diff --git a/src/fwp/fwp/lib/fwp/tests/fwp_prototest/fwp_sendrecv_test2.c b/src/fwp/fwp/lib/fwp/tests/fwp_prototest/fwp_sendrecv_test2.c
new file mode 100644 (file)
index 0000000..c42de6a
--- /dev/null
@@ -0,0 +1,123 @@
+/**
+ * \file fwp_sendrecv_test2.c  
+ *
+ * This a test application that:
+ * - creates vres without negotiation
+ * - creates reliable send endpoint
+ * - cretaes receiver thread and receive endpoint within it 
+ * - binds that endpoint to vres
+ * - sends two messages
+ * - receives messages
+ *
+ */
+#define CONFIGURE_FWP_MNGT 0
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <arpa/inet.h>
+
+#define MSGN 2
+
+fwp_endpoint_attr_t  attr;
+
+void* receiver(void* arg)
+{
+       struct fwp_endpoint *repoint1;
+       int i,len;
+       char buffer[30];
+       fwp_addr_t from;
+       
+       printf("Creating receive endpoint\n");
+       if (fwp_receive_endpoint_create(7777, &attr,&repoint1) < 0){
+               perror("Error while creating receive endpoint\n");
+               return NULL;
+       }
+               
+       printf("Receive endpoint created \n");
+       for (i = 0; i < MSGN; i++) {
+               if ((len = fwp_recv(repoint1, buffer, sizeof(buffer), &from,
+                        0)) < 0) {
+                       perror("Error while receiving data::");
+                       return NULL;
+               } else {
+                       printf("Received %s\n",buffer);
+                       //for (j = 0 ; j < 10; i++)
+                       //      printf("%c", buffer[i]);
+
+               }
+               printf("END\n");
+       }
+
+       return NULL;
+}
+
+int main()
+{
+       fwp_vres_t *vres1;
+       struct fwp_vres_params vparam1, vparam2;
+       char msg1[] = "Hello1";
+       char msg2[] = "Hello2";
+       struct fwp_endpoint *sepoint1;
+       pthread_t thread;
+       
+       vparam1.ac_id = FWP_AC_VO; 
+       vparam1.budget = 100;
+       vparam1.period.tv_sec = 0; 
+       vparam1.period.tv_nsec = 10000; 
+
+       vparam2.ac_id = FWP_AC_BK; 
+       vparam2.budget = 100;
+       vparam2.period.tv_sec = 0;
+       vparam2.period.tv_nsec = 100000;
+
+       printf("Start\n");
+       if (fwp_init() != 0) {
+               printf("FWP initialization failed!\n");
+               return -1;
+       }
+       
+       fwp_endpoint_attr_init(&attr);
+       fwp_endpoint_attr_setreliability(&attr, FWP_EPOINT_RELIABLE);
+       
+       pthread_create(&thread, NULL, &receiver, (void*) NULL);
+       printf("Create vres1, vres2\n");
+       if (fwp_vres_create(&vparam1, &vres1) < 0) {
+               printf("Unable to create vres1\n");
+               return -1;
+       }
+       printf("Vres1 created \n");
+       
+       if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), 7777, &attr, 
+                                       &sepoint1) < 0) {
+               return -1;
+       }
+       printf("Send endpoint 1 created\n");
+       fwp_send_endpoint_bind(sepoint1, vres1);
+       
+       fwp_send_sync(sepoint1, msg1, sizeof(msg1));
+       printf("Sent msg1\n");
+       fwp_send_sync(sepoint1, msg2, sizeof(msg2));
+       printf("Sent msg2\n");
+       
+       pthread_join(thread, (void**) NULL);    
+       /*if (fwp_vres_destroy(vres1) < 0) {
+               perror("Unable to destroy vres1\n");
+               return -1;
+       }
+       printf("Vres1 destroyed\n");
+       
+       if (fwp_vres_destroy(vres2) < 0){
+               perror("Unable to destroy vres2\n");
+               return -1;
+       }       
+       printf("Vres2 destroyed\n");
+       */
+
+       printf("Test PASSED!\n");
+       scanf("Press key");     
+       
+       return 0;
+}
diff --git a/src/fwp/fwp/lib/fwp/tests/fwp_vrestest/Makefile b/src/fwp/fwp/lib/fwp/tests/fwp_vrestest/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/lib/fwp/tests/fwp_vrestest/Makefile.omk b/src/fwp/fwp/lib/fwp/tests/fwp_vrestest/Makefile.omk
new file mode 100644 (file)
index 0000000..d631f49
--- /dev/null
@@ -0,0 +1,5 @@
+test_PROGRAMS = fwp_vrestest1  fwp_vrestest2
+CFLAGS+= -D_FWP_INTERNALS_
+fwp_vrestest1_SOURCES+= fwp_vrestest1.c
+fwp_vrestest2_SOURCES+= fwp_vrestest2.c
+lib_LOADLIBES += fwp pthread rt ulut 
diff --git a/src/fwp/fwp/lib/fwp/tests/fwp_vrestest/fwp_vrestest1.c b/src/fwp/fwp/lib/fwp/tests/fwp_vrestest/fwp_vrestest1.c
new file mode 100644 (file)
index 0000000..fc0faab
--- /dev/null
@@ -0,0 +1,99 @@
+/**
+ * \file fwp_vrestest1.c  
+ *
+ * This a test application that:
+ * - creates vres without negotiation
+ * - creates send and receive endpoint 
+ * - binds that endpoint to vres
+ * - in cycle (NUM loops) sends messages and prints send time
+ * - receives messages
+ * - destroys vres
+ *
+ */
+#define  CONFIGURE_FWP_MNGT 0
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+#include <time.h>
+
+#define  NUM  10000
+
+int main()
+{
+//     struct sockaddr_in local_addr, rem_addr, from;
+        ssize_t len;
+       fwp_vres_t *vres1, *vres2;
+       struct fwp_vres_params vparam1;
+       char msg1[15];
+       char buffer[30];
+       struct fwp_endpoint *sepoint, *repoint;
+       int count;
+       struct timespec  sendtime;
+       fwp_endpoint_attr_t attr;
+       unsigned int from;
+       
+       fwp_endpoint_attr_init(&attr);
+
+       vparam1.ac_id = FWP_AC_VO; 
+       vparam1.budget = 100;
+       vparam1.period.tv_sec = 2; 
+       vparam1.period.tv_nsec = 111111; 
+
+       printf("Start\n");
+       if (fwp_init() != 0) {
+               printf("fwp_init failed!\n");
+               return -1;
+       }       
+       
+       printf("Create vres1\n");
+       if ((fwp_vres_create(&vparam1, &vres1) < 0)) {
+               printf("Unable to create vres1\n");
+               return -1;
+       }
+       printf("Vres1 created\n");
+       
+       printf("Create vres2\n");
+       if ((fwp_vres_create(&vparam1, &vres2) < 0)) {
+               printf("Unable to create vres2\n");
+               return -1;
+       }
+       printf("Vres2 created\n");
+       /* local_addr should be handled when creating socket */
+       if (fwp_receive_endpoint_create(7777, &attr, &repoint) < 0) {
+               return -1;
+       }
+       printf("Receive endpoint created\n");
+       
+       if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), 7777, &attr, 
+                                    &sepoint) < 0){
+               return -1;
+       }
+       printf("Send endpoint 1 created\n");
+       fwp_send_endpoint_bind(sepoint, vres1);
+       
+       for (count = 0; count < NUM; count++) { 
+               sprintf(msg1,"msg%d",count);
+               fwp_send_sync(sepoint, msg1, sizeof(msg1));
+               
+               clock_gettime(CLOCK_MONOTONIC, &sendtime);
+               printf("Sent: sec = %ld nsec = %ld \n", sendtime.tv_sec,
+                      sendtime.tv_nsec);
+               
+               if ((len = fwp_recv(repoint, buffer, sizeof(buffer), &from, 0)) < 0) {
+                       perror("Error while receiving data");
+                       return -1;
+               } 
+                       else printf("Received - %s\n", buffer);
+       }
+
+       if (fwp_vres_destroy(vres1) < 0) {
+               perror("Unable to destroy vres1\n");
+               return -1;
+       }
+       printf("Vres1 detroyed\n");
+       printf("Test PASSED!\n");
+       return 0;
+}
diff --git a/src/fwp/fwp/lib/fwp/tests/fwp_vrestest/fwp_vrestest2.c b/src/fwp/fwp/lib/fwp/tests/fwp_vrestest/fwp_vrestest2.c
new file mode 100644 (file)
index 0000000..e43ffd4
--- /dev/null
@@ -0,0 +1,141 @@
+/**
+ * \file fwp_vrestest2.c  
+ *
+ * This a test application that:
+ * - creates vres without negotiation
+ * - creates send and receive endpoint 
+ * - binds that endpoint to vres
+ * - in cycle (NUM loops) sends messages in separate thread and 
+ *   prints send time
+ * - receives messages in separate receiver thread
+ * - destroys vres
+ *
+ */
+#define  CONFIGURE_FWP_MNGT 0
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <fwp_utils.h>
+
+#define  NUM  20
+#define  PORT 65111
+
+int exit_flag = 0;
+fwp_endpoint_attr_t attr;
+       
+void* sender()
+{
+       struct fwp_endpoint *sepoint;
+       fwp_vres_t *vres;
+       struct fwp_vres_params vparam1;
+       char msg1[10];
+       int count;
+       /*struct timespec  sendtime;*/
+       
+       vparam1.ac_id = FWP_AC_VO; 
+       vparam1.budget = 3;
+       vparam1.period.tv_sec = 5; 
+       vparam1.period.tv_nsec = 0; 
+       
+       printf("Create vres1\n");
+       if (fwp_vres_create(&vparam1, &vres) < 0) {
+               printf("Unable to open vres1\n");
+               return NULL;
+       }
+       printf("Vres1 created\n");
+       
+       if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), PORT, &attr, 
+               &sepoint) < 0){
+               return NULL;
+       }
+       printf("Send endpoint 1 created\n");
+       fwp_send_endpoint_bind(sepoint, vres);
+       
+       sleep(2);
+       //for (count = 0; count < NUM; count++) {       
+       fwp_set_rt_prio(90);
+       
+       count = 0;
+       while (count < NUM){
+               count++;
+               sprintf(msg1,"msg%d sent\n",count);
+               fwp_send_sync(sepoint, msg1, sizeof(msg1));
+       
+               printf(msg1);   
+               /*clock_gettime(CLOCK_MONOTONIC, &sendtime);
+               FWP_DEBUG("Sent %d: sec = %ld nsec = %ld \n", count,
+                               sendtime.tv_sec, sendtime.tv_nsec);
+               usleep(1000);*/
+       }
+       
+       while (!(exit_flag)) {
+               sleep(1);
+       }
+       
+       if (fwp_vres_destroy(vres) < 0) {
+               perror("Unable to destroy vres1\n");
+               return NULL;
+       }
+       printf("Vres1 destroyed\n");
+
+       return NULL;
+} 
+
+void* receiver()
+{
+        ssize_t len;
+       char buffer[30];
+       struct fwp_endpoint *repoint;
+       int count;
+       struct timespec recvtime;
+       fwp_addr_t      from;
+       
+       /* local_addr should be handled when creating socket */
+       if (fwp_receive_endpoint_create(PORT, &attr, &repoint) < 0){
+               perror("Not initialized\n");
+               return NULL;
+       }
+       printf("Receive endpoint created\n");
+       
+       for (count = 1; count <= NUM; count++) {        
+               
+               if ((len = fwp_recv(repoint, buffer, sizeof(buffer), &from, 0)) < 0){
+                       perror("Error while receiving data");
+                       return NULL;
+               } 
+                       else printf("Received - %s\n", buffer);
+               
+               clock_gettime(CLOCK_MONOTONIC, &recvtime);
+               printf("Received %d: sec = %ld nsec = %ld \n", count, 
+                      recvtime.tv_sec, recvtime.tv_nsec);
+       }
+
+       exit_flag = 1;
+
+       return NULL;
+}
+
+int main()
+{
+//     struct sockaddr_in local_addr, rem_addr, from;
+       pthread_attr_t  thattr;
+       pthread_t       thread;
+
+       printf("Start\n");
+       fwp_init();
+       
+       fwp_endpoint_attr_init(&attr);
+       pthread_attr_init(&thattr);
+       pthread_create(&thread, &thattr, sender, NULL); 
+       pthread_create(&thread, &thattr, receiver, NULL); 
+       pthread_join(thread, (void**) NULL);    
+
+       printf("Test PASSED!\n");
+       return 0;
+}
diff --git a/src/fwp/fwp/mngr/Makefile b/src/fwp/fwp/mngr/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/mngr/Makefile.omk b/src/fwp/fwp/mngr/Makefile.omk
new file mode 100644 (file)
index 0000000..51a24be
--- /dev/null
@@ -0,0 +1,7 @@
+bin_PROGRAMS = frm_fwp
+frm_fwp_SOURCES = fwp_mngr.c fwp_admctrl.c
+frm_fwp_LIBS = frm forb contract fosa rt ulut fcb_client
+
+#include_HEADERS = res_fwp.h
+CFLAGS += -D_FWP_INTERNALS_
+lib_LOADLIBES+= frsh 
diff --git a/src/fwp/fwp/mngr/fwp_admctrl.c b/src/fwp/fwp/mngr/fwp_admctrl.c
new file mode 100644 (file)
index 0000000..b6d6c43
--- /dev/null
@@ -0,0 +1,250 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#include <fres_sa_scenario.h>
+#include <fwp.h>
+#include "fwp_idl.h"
+#include "fwp_admctrl.h"
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include "fwp_utils.h"
+
+UL_LOG_CUST(ulogd_fwp_admctrl);
+ul_log_domain_t ulogd_fwp_admctrl = {UL_LOGL_MSG, "fwp_admctrl"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fwp_admctrl_logreg_domains, ulogd_fwp_admctrl);
+
+/* TODO: Find out the real value and determine what influences it (MTU
+ *      of the interface minus header sizes?).  */
+#define MTU 1472
+#define UDP_HEADER_SIZE 8
+#define IP_HEADER_SIZE 20
+#define LLC_HEADER_SIZE 2      /* ??? */
+#define MAC_HEADER_SIZE 26     /* With QoS field added */
+#define MAC_FCS_SIZE 4
+
+#define RTS_FRAME_SIZE 20
+#define CTS_FRAME_SIZE 14
+#define ACK_FRAME_SIZE 14
+
+#define ASLOTTIME_USEC 20      /* 802.11g-2003 p. 46 */
+#define ASIFSTIME_USEC 10
+#define ADIFSTIME_USEC (ASIFSTIME_USEC + 2*ASLOTTIME_USEC)
+#define AAIFSTIME_USEC(n) (ASIFSTIME_USEC + (n)*ASLOTTIME_USEC)
+
+/* Default values from 802.11e */
+const int aifsn[FWP_AC_NUM] = { 2, 2, 3, 7 };
+const int cwmin[FWP_AC_NUM] = { 3, 7, 15, 15 };
+
+/* Experimental konstants - weight of backoff */
+const int pisvejc[FWP_AC_NUM] = { 6, 5, 2, 2 };
+
+int fwp_reserved_utilization;
+
+/**
+ * Calucaltes frame duration in microseconds. If the real duration is
+ * represented by a fractional number, the value is rounded up.
+ *
+ * @param length Number of bytes in PSDU.
+ * @param rate_bps Transmit rate of PSDU. The rate should correspond
+ *            to other parameters accoring to 19.3.2 (802.11g)
+ * @param erp_ofdm Whether Extended Rate PHY (part of 802.11g) and ERP-OFDM
+ *            modulation is used.
+ * @param short_preamble Whether short preamble (HR/DSSS/short) is
+ *            used (802.11b)
+ *
+ * @return The number of microseconds or a negative number in case of error.
+ */
+static int frame_duration(uint16_t length, int rate_bps, bool erp_ofdm, bool short_preamble)
+{
+       uint32_t duration_usec = 0;
+
+       if (!erp_ofdm) {
+               duration_usec = ((int64_t)(length) * 8 * SEC_TO_USEC / rate_bps);
+               if (short_preamble) {
+                       /* For HR/DSSS/short (2, 5.5 and 11 Mbit,
+                        * 802.11b-1999), also for DSSS-OFDM rates and
+                        * ERP-PBCC rates.
+                        * Preamble sent at 1 MBit, header at 2 Mbit */
+                       duration_usec += 72/*bits*/+48/*bits*//2;
+               } else {
+                       /* For DSSS PHY (1 and 2 Mbit rates,
+                        * 802.11-1999) and for DSS-OFDM and ERP-PBCC
+                        * rates. Always sent at 1 MBit */
+                       duration_usec += 144/*bits*/+48/*bits*/;
+               }
+       } else {
+#define MBIT_TO_INDEX(rate_Mbps)  ((rate_Mbps)/3 - 2)
+               const int N_dbps[] = {
+                       [MBIT_TO_INDEX(6)] = 24,
+                       [MBIT_TO_INDEX(9)] = 36,
+                       [MBIT_TO_INDEX(12)] = 48,
+                       [MBIT_TO_INDEX(18)] = 72,
+                       [MBIT_TO_INDEX(24)] = 96,
+                       [MBIT_TO_INDEX(36)] = 144,
+                       [MBIT_TO_INDEX(48)] = 192,
+                       [MBIT_TO_INDEX(54)] = 216
+               };
+               int rate_idx = MBIT_TO_INDEX(rate_bps/1000/1000);
+#undef MBIT_TO_INDEX
+               if (rate_idx < 0 ||
+                   rate_idx >= sizeof(N_dbps)/sizeof(*N_dbps) ||
+                   N_dbps[rate_idx] == 0)
+                       return -1;
+
+               duration_usec += 16 + 4; /* Preamble, SIGNAL */
+               int bits =
+                       16 +        /* SERVICE */
+                       length * 8 +
+                       6;          /* tail bits */
+               int Nsym = (bits + N_dbps[rate_idx] - 1)/N_dbps[rate_idx];
+
+               duration_usec += Nsym * 4;
+
+               duration_usec += 6; /* signal extension */
+       }
+       return duration_usec;
+}
+
+int fwp_admctrl_utilization(struct fres_sa_scenario *scenario, void *priv,
+                           bool *schedulable)
+{
+       long long utilization = 0;
+       struct frm_fwp_priv *pr = priv;
+       const int rate = pr->rate_mbps*1000*1000;
+       struct fres_sa_contract *c;
+       long int period_usec;
+       fres_block_fwp_sched *fwp_sched;
+
+       size_t bytes; 
+       long int duration_usec, tmp_usec;
+       int fragments;
+       int ac = FWP_AC_VO; 
+       
+       fres_sa_scenario_for_each_no_cancel_contract(scenario, c) {
+               fres_block_basic *basic;
+               char id[40];
+               fres_contract_id_to_string(id, &c->contract->id, sizeof(id));
+               basic = fres_contract_get_basic(c->contract);
+
+               frsh_network_budget_to_bytes(FRSH_NETPF_FWP,&basic->budget,&bytes);
+               ul_logmsg("processing: id=%s, period=%ld ms, budget=%lu bytes\n",
+                      id,
+                      fosa_rel_time_to_msec(basic->period),
+                      (long unsigned int)bytes);
+
+               period_usec = basic ? fosa_rel_time_to_msec(basic->period)*1000 : 0;
+
+               /* Calculate protocol overhead */
+               fragments = (bytes + MTU - 1) / MTU;
+
+               if (fragments == 0 && period_usec != 0)
+                       continue;
+
+               const int data_overhead = UDP_HEADER_SIZE + IP_HEADER_SIZE +
+                       LLC_HEADER_SIZE + MAC_FCS_SIZE;
+
+               duration_usec = frame_duration(data_overhead + bytes%MTU, rate, 
+                                              pr->erp_ofdm, pr->short_preamble);
+               tmp_usec = frame_duration(data_overhead + MTU, rate,
+                                         pr->erp_ofdm, pr->short_preamble);
+               duration_usec += tmp_usec*(fragments-1);
+               /* Add average backoff - assume there is no collision */
+               tmp_usec = ASLOTTIME_USEC*fragments*pisvejc[ac];
+               duration_usec += (aifsn[ac] + cwmin[ac]/2)*tmp_usec;
+               /* We use ACK and ignore burst */
+               tmp_usec = frame_duration(ACK_FRAME_SIZE, rate,
+                                         pr->erp_ofdm, pr->short_preamble)
+                       + ASIFSTIME_USEC; 
+               duration_usec += fragments * tmp_usec; 
+               //printf("duration: %ld ms\n", duration_usec/1000);
+
+               /* TODO: If STA-to-STA, multiply it by two. Note that
+                * AP may use different values for backoff. */
+               duration_usec *= 2; /* For demo, we have always STA-to-STA */
+
+               if (c->contract == c->new) {
+                       if (period_usec == 0) {
+                               ul_logmsg("Period is zero!\n");
+                               goto not_schedulable;
+                       }
+
+                       frsh_rel_time_t deadline;
+                       long int d;
+                       if (fres_contract_get_deadline(&c->contract, &deadline)) {
+                               d = fosa_rel_time_to_msec(deadline)*1000;
+                       } else {
+                               d = 100/*sec*/*1000*1000;
+                       }
+                       if (d < 30/*msec*/*1000) {
+                               ul_logmsg("Deadline shorter than 30 ms!\n");
+                               goto not_schedulable;
+                       };
+                       
+                       fwp_sched = malloc(sizeof(*fwp_sched));
+                       fwp_sched->ac_id =
+                               d <  100*1000 ? FWP_AC_VO :
+                               d <  500*1000 ? FWP_AC_VI :
+                               d < 1000*1000 ? FWP_AC_BE :
+                               FWP_AC_BK;
+                       fres_contract_add_block(c->contract, FRES_BLOCK_FWP_SCHED, fwp_sched);
+               }
+
+               utilization += (long long)duration_usec * 10000 / period_usec;
+       }
+       
+       if (utilization >= 10000 * 96/100 && !pr->bypass) {
+               goto not_schedulable;
+       }
+       scenario->utilization = utilization/100; /* For GUI */
+
+       ul_logmsg("accepted (utilization=%lld%%)\n", utilization/100);
+       *schedulable = true;
+       return 0;
+
+not_schedulable:
+       ul_logmsg("rejected (utilization=%lld%%)\n", utilization/100);
+       *schedulable = false;
+       return 0;
+}
diff --git a/src/fwp/fwp/mngr/fwp_admctrl.h b/src/fwp/fwp/mngr/fwp_admctrl.h
new file mode 100644 (file)
index 0000000..ae4207c
--- /dev/null
@@ -0,0 +1,61 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#ifndef _FWP_ADMCTRL_H
+#define _FWP_ADMCTRL_H
+
+#include <frsh_distributed.h>
+
+struct frm_fwp_priv {
+       int rate_mbps;
+       bool erp_ofdm;
+       bool short_preamble;
+       bool bypass;
+};
+
+int fwp_admctrl_utilization(struct fres_sa_scenario *scenario, void *priv,
+                                bool *schedulable);
+
+#endif /*_FWP_AMDCTRL_H */
diff --git a/src/fwp/fwp/mngr/fwp_mngr.c b/src/fwp/fwp/mngr/fwp_mngr.c
new file mode 100644 (file)
index 0000000..c94328a
--- /dev/null
@@ -0,0 +1,173 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners:                */
+/*                                                                       */
+/*   Universidad de Cantabria,              SPAIN                        */
+/*   University of York,                    UK                           */
+/*   Scuola Superiore Sant'Anna,            ITALY                        */
+/*   Kaiserslautern University,             GERMANY                      */
+/*   Univ. Politécnica  Valencia,           SPAIN                       */
+/*   Czech Technical University in Prague,  CZECH REPUBLIC               */
+/*   ENEA                                   SWEDEN                       */
+/*   Thales Communication S.A.              FRANCE                       */
+/*   Visual Tools S.A.                      SPAIN                        */
+/*   Rapita Systems Ltd                     UK                           */
+/*   Evidence                               ITALY                        */
+/*                                                                       */
+/*   See http://www.frescor.org for a link to partners' websites         */
+/*                                                                       */
+/*          FRESCOR project (FP6/2005/IST/5-034026) is funded            */
+/*       in part by the European Union Sixth Framework Programme         */
+/*       The European Union is not liable of any use that may be         */
+/*       made of this code.                                              */
+/*                                                                       */
+/*                                                                       */
+/*  This file is part of FWP (Frescor WLAN Protocol)                     */
+/*                                                                       */
+/* FWP is free software; you can redistribute it and/or modify it        */
+/* under terms of the GNU General Public License as published by the     */
+/* Free Software Foundation; either version 2, or (at your option) any   */
+/* later version.  FWP is distributed in the hope that it will be        */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty   */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   */
+/* General Public License for more details. You should have received a   */
+/* copy of the GNU General Public License along with FWP; see file       */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                             */
+/*                                                                       */
+/* As a special exception, including FWP header files in a file,         */
+/* instantiating FWP generics or templates, or linking other files       */
+/* with FWP objects to produce an executable application, does not       */
+/* by itself cause the resulting executable application to be covered    */
+/* by the GNU General Public License. This exception does not            */
+/* however invalidate any other reasons why the executable file might be  */
+/* covered by the GNU Public License.                                    */
+/**************************************************************************/
+#include <frm_generic.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <getopt.h>
+#include <fres_sa_scenario.h>
+#include <stdbool.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <fwp_res.h>
+#include <stdio.h>
+#include "fwp_admctrl.h"
+
+#if 0
+static
+int dummy_admission_test(struct fres_sa_scenario *scenario, void *priv, 
+                               bool *schedulable)
+{
+       struct fres_sa_contract *c;
+
+       printf("Dummy admission test:\n");
+
+       fres_sa_scenario_for_each_no_cancel_contract(scenario, c) {
+               fres_block_basic *basic;
+               char id[40];
+               fres_contract_id_to_string(id, &c->contract->id, sizeof(id));
+               basic = fres_contract_get_basic(c->contract);
+
+               printf("  processing: id=%s, period=%ld ms, budget=%ld ms\n",
+                      id,
+                      fosa_rel_time_to_msec(basic->period),
+                      fosa_rel_time_to_msec(basic->budget));
+
+       }
+       *schedulable = scenario->num_contracts <= 3;
+       printf("=> %s\n", schedulable?"schedulable":"not schedulable");
+               
+       return 0;
+}
+#endif
+
+struct frm_fwp_priv priv = {
+       .rate_mbps = 1,
+       .erp_ofdm = false,
+       .short_preamble = false,
+};
+
+static const struct fres_res_manager frm = {
+       .res_type = FRSH_RT_NETWORK,
+       .res_id = FRSH_NETPF_FWP,
+       //.admission_test = dummy_admission_test,
+       .name = "WLAN",
+       .admission_test = fwp_admctrl_utilization,
+       .priv = &priv,
+};
+
+static struct option long_opts[] = {
+    { "loglevel",         required_argument, 0, 'l' },
+    { "bitrate",         required_argument, 0, 'b' },
+    { "ofdm",                    no_argument,       0, 'o' },
+    { "short-preamble",  no_argument,       0, 's' },
+    { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+       printf("usage: fwpmngr [ options ]\n");
+       printf("  -l, --loglevel <number>|<domain>=<number>,...\n");
+       printf("  -b, --bitrate <mbits/s>\n");
+       printf("  -o, --ofdm\n");
+       printf("  -s, --short-preamble\n");
+       printf("  -h, --help\n");
+}
+
+int main(int argc, char *argv[])
+{
+       forb_orb orb;
+       int ret;
+       forb_init_attr_t attr = { .orb_id = "org.frescor.frm.fwp" };
+       int  opt;
+       bool opt_daemon = false;
+       char *opt_pidfile = NULL;
+
+       if (getenv("FWP_BYPASS"))
+               priv.bypass = true;
+
+
+       while ((opt = getopt_long(argc, argv, "b:d:hl:os", &long_opts[0], NULL)) != EOF) {
+               switch (opt) {
+                       case 'd':
+                               opt_daemon = true;
+                               opt_pidfile = optarg;
+                               break;
+                       case 'l':
+                               ul_log_domain_arg2levels(optarg);
+                               break;
+                       case 'b':
+                               priv.rate_mbps = atol(optarg);
+                               break;
+                       case 's':
+                               priv.short_preamble = true;
+                               break;
+                       case 'o':
+                               priv.erp_ofdm = true;
+                               break;
+                       case 'h':
+                       /*default:*/
+                               usage();
+                               exit(opt == 'h' ? 0 : 1);
+               }
+       }
+
+       if (opt_daemon)
+               forb_daemon_prepare(opt_pidfile);
+
+       orb = forb_init(&argc, &argv, &attr);
+       if (!orb) error(1, errno, "forb_init");
+       
+       fres_block_register_fwp();
+       ret = frm_register_and_run(orb, &frm);
+
+       if (ret != 0) {
+               error(1, errno, "frm_generic_run");
+       }
+       
+       return 0;
+}
diff --git a/src/fwp/fwp/old.mngr/Makefile b/src/fwp/fwp/old.mngr/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/old.mngr/Makefile.omk b/src/fwp/fwp/old.mngr/Makefile.omk
new file mode 100644 (file)
index 0000000..9af7d74
--- /dev/null
@@ -0,0 +1,13 @@
+bin_PROGRAMS = fwpmngr
+CFLAGS += -Wall -D_REENTRANT -g -D_FWP_INTERNALS_
+#fwpagent_SOURCES+= fwp_agent.c 
+#fwpmngr_SOURCES+= fwp_participant.c fwp_mngr.c fwp_contract_table.c\
+                 fwp_agent_table.c fwp_admctrl.c
+fwpmngr_SOURCES+= fwp_mngr.c 
+fwpmngr_SOURCES+=  fwp_admctrl.c
+fwpmngr_SOURCES+= admtest_utilization.c
+#fwpmngr_SOURCES+= gui.c
+
+lib_LOADLIBES+= fwp ulut pthread rt
+#lib_LOADLIBES+= fwp ulut pthread rt ncurses
+
diff --git a/src/fwp/fwp/old.mngr/admtest_utilization.c b/src/fwp/fwp/old.mngr/admtest_utilization.c
new file mode 100644 (file)
index 0000000..babee4b
--- /dev/null
@@ -0,0 +1,184 @@
+#include "fwp_admctrl.h"
+#include <fwp_utils.h>
+#include <stdint.h>
+#include <fwp_conf.h>
+#include <stdbool.h>
+#include <fwp_participant.h>
+#include "fwp_participant_table.h"
+#include "fwp_foreach.h"
+
+/* TODO: Find out the real value and determine what influences it (MTU
+ *      of the interface minus header sizes?).  */
+#define MTU 1472
+#define UDP_HEADER_SIZE 8
+#define IP_HEADER_SIZE 20
+#define LLC_HEADER_SIZE 2      /* ??? */
+#define MAC_HEADER_SIZE 26     /* With QoS field added */
+#define MAC_FCS_SIZE 4
+
+#define RTS_FRAME_SIZE 20
+#define CTS_FRAME_SIZE 14
+#define ACK_FRAME_SIZE 14
+
+#define BITRATE_BPS (1000*1000)
+#define ASLOTTIME_USEC 20      /* 802.11g-2003 p. 46 */
+#define ASIFSTIME_USEC 10
+#define ADIFSTIME_USEC (ASIFSTIME_USEC + 2*ASLOTTIME_USEC)
+#define AAIFSTIME_USEC(n) (ASIFSTIME_USEC + (n)*ASLOTTIME_USEC)
+
+#define TXTIME_USEC(bytes) ((int64_t)(bytes) * 8 * SEC_TO_USEC / BITRATE_BPS)
+
+
+/* Default values from 802.11e */
+const int aifsn[FWP_AC_NUM] = { 2, 2, 3, 7 };
+const int cwmin[FWP_AC_NUM] = { 3, 7, 15, 15 };
+
+/* Experimental konstants - weight of backoff */
+const int pisvejc[FWP_AC_NUM] = { 6, 5, 2, 2 };
+
+int fwp_reserved_utilization;
+
+/**
+ * Calucaltes frame duration in microseconds. If the real duration is
+ * represented by a fractional number, the value is rounded up.
+ *
+ * @param length Number of bytes in PSDU.
+ * @param rate_bps Transmit rate of PSDU. The rate should correspond
+ *            to other parameters accoring to 19.3.2 (802.11g)
+ * @param erp_ofdm Whether Extended Rate PHY (part of 802.11g) and ERP-OFDM
+ *            modulation is used.
+ * @param short_preamble Whether short preamble (HR/DSSS/short) is
+ *            used (802.11b)
+ *
+ * @return The number of microseconds or a negative number in case of error.
+ */
+static int frame_duration(uint16_t length, int rate_bps, bool erp_ofdm, bool short_preamble)
+{
+       uint32_t duration_usec;
+
+       if (!erp_ofdm) {
+               duration_usec = ((int64_t)(length) * 8 * SEC_TO_USEC / rate_bps);
+               if (short_preamble) {
+                       /* For HR/DSSS/short (2, 5.5 and 11 Mbit,
+                        * 802.11b-1999), also for DSSS-OFDM rates and
+                        * ERP-PBCC rates.
+                        * Preamble sent at 1 MBit, header at 2 Mbit */
+                       duration_usec += 72/*bits*/+48/*bits*//2;
+               } else {
+                       /* For DSSS PHY (1 and 2 Mbit rates,
+                        * 802.11-1999) and for DSS-OFDM and ERP-PBCC
+                        * rates. Always sent at 1 MBit */
+                       duration_usec += 144/*bits*/+48/*bits*/;
+               }
+       } else {
+#define MBIT_TO_INDEX(rate_Mbps)  ((rate_Mbps)/3 - 2)
+               const int N_dbps[] = {
+                       [MBIT_TO_INDEX(6)] = 24,
+                       [MBIT_TO_INDEX(9)] = 36,
+                       [MBIT_TO_INDEX(12)] = 48,
+                       [MBIT_TO_INDEX(18)] = 72,
+                       [MBIT_TO_INDEX(24)] = 96,
+                       [MBIT_TO_INDEX(36)] = 144,
+                       [MBIT_TO_INDEX(48)] = 192,
+                       [MBIT_TO_INDEX(54)] = 216
+               };
+               int rate_idx = MBIT_TO_INDEX(rate_bps/1000/1000);
+#undef MBIT_TO_INDEX
+               if (rate_idx < 0 ||
+                   rate_idx >= sizeof(N_dbps)/sizeof(*N_dbps) ||
+                   N_dbps[rate_idx] == 0)
+                       return -1;
+
+               duration_usec += 16 + 4; /* Preamble, SIGNAL */
+               int bits =
+                       16 +        /* SERVICE */
+                       length * 8 +
+                       6;          /* tail bits */
+               int Nsym = (bits + N_dbps[rate_idx] - 1)/N_dbps[rate_idx];
+
+               duration_usec += Nsym * 4;
+
+               duration_usec += 6; /* signal extension */
+       }
+       return duration_usec;
+}
+
+void fwp_admctrl_utilization(fwp_contract_data_t *contdata_new)
+{
+       int utilization = 0;
+
+       const int rate = 1*1000*1000;
+       const bool erp_ofdm = false;
+       const bool short_preamble = false;
+       fwp_contract_data_t *contdata;
+
+       struct foreach_contract fec;
+       fec.contdata_new = contdata_new;
+       
+       for (contdata=foreach_contract_begin(&fec);
+            contdata;
+            contdata=foreach_contract_next(&fec)) {
+               int bytes, duration_usec, fragments;
+               struct fwp_contract *contract = &contdata->contract;
+               int ac = FWP_AC_VO; /* FIXME: assign to AC before this
+                                    * loop based on deadlines */
+               /* Calculate protocol overhead */
+
+               bytes = contract->budget;
+               fragments = (bytes + MTU - 1) / MTU;
+
+               if (fragments == 0)
+                       continue;
+
+               const int data_overhead = UDP_HEADER_SIZE + IP_HEADER_SIZE +
+                       LLC_HEADER_SIZE + MAC_FCS_SIZE;
+
+               duration_usec = frame_duration(data_overhead + bytes%MTU, rate, erp_ofdm, short_preamble);
+               duration_usec += frame_duration(data_overhead + MTU, rate, erp_ofdm, short_preamble)*(fragments-1);
+
+               /* Add average backoff - assume there is no collision */
+               duration_usec += (aifsn[ac] + cwmin[ac]/2)*ASLOTTIME_USEC*fragments*pisvejc[ac];
+               /* We use ACK and ignore burst */
+               duration_usec += fragments * (ASIFSTIME_USEC +
+                                 frame_duration(ACK_FRAME_SIZE, rate, erp_ofdm, short_preamble));
+
+               /* TODO: If STA-to-STA, multiply it by two. Note that
+                * AP may use different values for backoff. */
+               duration_usec *= 2; /* For demo, we have always STA-to-STA */
+               if (contract->period_usec == 0) {
+                       if (contdata == contdata_new) {
+                               contdata->status = FWP_CONT_NOTNEGOTIATED;
+                               return;
+                       }
+               }
+               utilization += (long long)(duration_usec * 10000) / contract->period_usec;
+       }
+
+       if (contdata_new) {
+               if (utilization >= 10000 * 96/100) {
+                       contdata_new->status = FWP_CONT_NOTNEGOTIATED;
+               } else {
+                       struct fwp_contract *c = &contdata_new->contract;
+                       int d = c->deadline_usec;
+                       if (d <= 0) d = 100*1000*1000;
+                       if (d < 50000) {
+                               contdata_new->status = FWP_CONT_NOTNEGOTIATED;
+                       } else {
+                               contdata_new->status = FWP_CONT_RESERVED;
+                       }
+
+                       contdata_new->vres_params.ac_id =
+                               d <  100*1000 ? FWP_AC_VO :
+                               d <  500*1000 ? FWP_AC_VI :
+                               d < 1000*1000 ? FWP_AC_BE :
+                               FWP_AC_BK;
+                       contdata_new->vres_params.budget = c->budget;
+                       contdata_new->vres_params.period_usec = c->period_usec; 
+               }
+       }
+
+       /* Update utilization for GUI */
+       if (contdata_new == NULL || contdata_new->status == FWP_CONT_RESERVED) {
+               fwp_reserved_utilization = utilization;
+       }
+}
diff --git a/src/fwp/fwp/old.mngr/fwp_admctrl.c b/src/fwp/fwp/old.mngr/fwp_admctrl.c
new file mode 100644 (file)
index 0000000..9661bbd
--- /dev/null
@@ -0,0 +1,17 @@
+#include "fwp_admctrl.h"
+#include "fwp_vres.h"
+
+static int nr_negotiated =0;
+/***/
+
+void fwp_admctrl_stupid(fwp_contract_data_t *contdata)
+{
+       contdata->vres_params.ac_id = FWP_AC_VI;
+       contdata->vres_params.budget = 100;
+       contdata->vres_params.period_usec = 20; 
+       
+       if (nr_negotiated <= 4) { 
+               nr_negotiated++;
+               contdata->status =  FWP_CONT_RESERVED;  
+       }
+}
diff --git a/src/fwp/fwp/old.mngr/fwp_admctrl.h b/src/fwp/fwp/old.mngr/fwp_admctrl.h
new file mode 100644 (file)
index 0000000..707a3db
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _FWP_ADMCTRL_H
+#define _FWP_ADMCTRL_H
+
+#include "fwp_contract_table.h"
+
+typedef void (*fwp_admctrl_test_t)(fwp_contract_data_t *contdata);
+
+void fwp_admctrl_stupid(fwp_contract_data_t *contdata);
+void fwp_admctrl_utilization(fwp_contract_data_t *contdata);
+
+extern int fwp_reserved_utilization;
+
+#endif /*_FWP_AMDCTRL_H */
diff --git a/src/fwp/fwp/old.mngr/fwp_foreach.h b/src/fwp/fwp/old.mngr/fwp_foreach.h
new file mode 100644 (file)
index 0000000..3758b28
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef FWP_FOREACH_H
+#define FWP_FOREACH_H
+
+#include <fwp_participant.h>
+#include "fwp_participant_table.h"
+
+struct foreach_contract {
+       fwp_participant_t *participant;    /**< Current participant */
+       fwp_contract_data_t *contdata;     /**< Current contract */
+       fwp_contract_data_t *contdata_new; /**< The contract being negotiated */
+};
+
+static inline fwp_contract_data_t *foreach_contract_begin(struct foreach_contract *fec)
+{
+       fec->contdata = NULL;
+       fec->participant = fwp_participant_table_foreach_begin();
+       while (1) {
+               if (fec->participant) {
+                       fec->contdata= fwp_contract_table_foreach_begin
+                                       (&fec->participant->contract_table);
+               } else {
+                       break;
+               }
+               if (fec->contdata == NULL) {
+                       fwp_contract_table_foreach_end(&fec->participant->contract_table);
+                       fec->participant = fwp_participant_table_foreach_next(fec->participant);
+                       continue;
+               }
+               break;
+       };
+
+       if (fec->contdata == NULL) {
+               fwp_participant_table_foreach_end();
+               fec->contdata = fec->contdata_new;
+       }
+       return fec->contdata;
+}
+
+static inline fwp_contract_data_t *foreach_contract_next(struct foreach_contract *fec)
+{
+       if (fec->contdata == fec->contdata_new) {
+               /* This was the last contract */
+               return NULL;
+       }
+       fec->contdata=fwp_contract_table_foreach_next(&fec->participant->contract_table, 
+                                                       fec->contdata);
+       while (1) {
+               if (fec->contdata == NULL) {
+                       fwp_contract_table_foreach_end(&fec->participant->contract_table);
+                       fec->participant = fwp_participant_table_foreach_next(fec->participant);
+                       if (fec->participant == NULL) {
+                               break;
+                       }
+                       fec->contdata= fwp_contract_table_foreach_begin(
+                                               &fec->participant->contract_table);
+                       continue;
+               }
+               break;
+       };
+
+       if (fec->contdata == NULL) {
+               fwp_participant_table_foreach_end();
+               fec->contdata = fec->contdata_new;
+       }
+       return fec->contdata;
+}
+
+#endif
diff --git a/src/fwp/fwp/old.mngr/fwp_mngr.c b/src/fwp/fwp/old.mngr/fwp_mngr.c
new file mode 100644 (file)
index 0000000..d201395
--- /dev/null
@@ -0,0 +1,380 @@
+#define CONFIGURE_FWP_MY_STREAM_ID 3000
+#define CONFIGURE_FWP_MNGR_ADDR "127.0.0.1"
+
+#include <error.h>
+#include <errno.h>
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include "fwp_contract_table.h"
+#include "fwp_participant_table.h"
+#include "fwp_admctrl.h"
+#include "fwp_mngt.h"
+#include "gui.h"
+
+#define FWP_MTU        2346
+#define BUFFSIZE       FWP_MTU 
+
+/* Admission control test */
+fwp_admctrl_test_t fwp_admctrl_test = &fwp_admctrl_utilization;
+
+/**
+ * fwp_mngt_input 
+ *
+ * Function waits for remote or local message 
+ * 
+ * @msgb  received message 
+ * \return 
+ * On success, it returns 0 and the pointer to received message in msgb parameter.
+ * On error, it returns negative error code
+ *
+ */
+int fwp_mngr_input(struct fwp_msgb **pmsgb)
+{
+       /* buffer and socket for incomming message */
+       static unsigned char    buffer[FWP_MTU];
+       struct fwp_msgb *msgb;
+       ssize_t size, expected;
+       struct fwp_msg_header *header = (void*)buffer;
+
+       FWP_DEBUG("Waiting for messages\n");
+       /* TODO: consider to replace with fwp_mngt_recv call */
+       size = fwp_recv(fwp_participant_this->epointd, buffer, sizeof(*header), 0);
+       if (size < 0) {
+               return size;
+       }
+       if (size < sizeof(*header)) {
+               return -EPROTO;
+               /* TODO: Use errno for error reporting */
+       }
+       expected = ntohs(header->length)-sizeof(*header);
+       size = fwp_recv(fwp_participant_this->epointd, buffer+size,
+                       expected, 0);
+       if (size < expected) {
+               return -EPROTO;
+       }
+        
+       /* For future: fwp_socket could be allocated behind data in msgb*/
+       if (!(msgb = fwp_msgb_alloc(ntohs(header->length)))) {
+               perror("No memory available.\n");
+               return -ENOMEM;
+       }
+       /*memcpy(fwp_msgb_put(msgb, len), buffer, len); */
+       msgb->data = buffer;
+       fwp_msgb_put(msgb, ntohs(header->length));
+       
+       *pmsgb = msgb;
+       return (0);
+}
+
+/** 
+ * Processes hello message.
+ * 
+ * @param msgb 
+ * @param participant_id 
+ * 
+ * @return Zero on success, -1 on error.
+ */
+int fwp_mngr_hello(fwp_msgb_t *msgb, fwp_participant_id_t participant_id)
+{
+       fwp_participant_info_t participant_info, my_info;
+       fwp_participant_t *participant;
+       fwp_endpoint_attr_t attr;
+       int ret;
+
+       FWP_DEBUG("Received HELLO msg from nodeid= %d appid= %d\n", 
+                       participant_id.node_id, participant_id.app_id);
+
+       fwp_endpoint_attr_init(&attr);
+       fwp_endpoint_attr_setreliability(&attr, FWP_MNGT_RELIABILITY);
+       /* Create a new participant */
+       fwp_msg_hello_out(msgb->data, &participant_info);
+       participant = fwp_participant_new(&participant_info);
+       if (!participant)
+               return -1;
+       ret = fwp_mngt_service_vres_create(&participant->service_contract,
+                                          &participant->vresd);
+       if (ret < 0)
+               goto err_vres;
+       ret = fwp_send_endpoint_create(participant->id.node_id, participant->stream_id,
+                                      &attr, &participant->epointd);
+       if (ret < 0)
+               goto err_endpoint;
+       ret = fwp_send_endpoint_bind(participant->epointd, participant->vresd);
+       if (ret < 0)
+               goto err_bind;
+       fwp_contract_table_init(&participant->contract_table);
+
+       /* Insert participant into table */
+       fwp_participant_table_insert(participant);
+
+       /* Send back hello msg with mngr`s info */
+       /* prepare hello message */
+       fwp_msgb_reset_data(msgb);
+       fwp_msgb_reserve(msgb, sizeof(struct fwp_msg_header));
+       
+       my_info.id = fwp_participant_this->id;
+       my_info.stream_id = fwp_participant_this->stream_id;
+
+       fwp_msg_hello_in(msgb->tail, &my_info);
+       fwp_msgb_put(msgb, sizeof(struct fwp_msg_hello));
+
+       /* Send hello to manager */
+       ret = fwp_mngt_send(FWP_MSG_HELLO, msgb, 
+                           fwp_participant_this, participant);
+       if (ret < 0)
+               goto err_send;
+
+       FWP_DEBUG("Sent HELLO msg from nodeid= %d appid= %d\n", 
+                       participant_id.node_id, participant_id.app_id);
+       return 0;
+err_send:
+       fwp_send_endpoint_unbind(participant->epointd);
+err_bind:
+       fwp_endpoint_destroy(participant->epointd);
+err_endpoint:
+       /* FIXME: This function is probably not the opposite of
+        * fwp_mngt_service_vres_create(), beacuse it doesn't delete
+        * the service contract. */
+       /*fwp_vres_destroy(participant->vresd);*/
+       fwp_contract_destroy(participant->service_contract);
+err_vres:
+       fwp_participant_delete(participant);
+       return -1;
+}
+
+int fwp_mngr_bye(fwp_msgb_t *msgb, fwp_participant_id_t participant_id)
+{      
+       fwp_participant_t *participant;
+       fwp_contract_data_t* contdata;
+
+       /* Find participant */
+       if (!(participant = fwp_participant_table_find(&participant_id))){
+               return -EPERM;
+       }
+
+       /* TODO: Check for errors */
+       fwp_participant_table_delete(participant);
+       fwp_send_endpoint_unbind(participant->epointd);
+       fwp_endpoint_destroy(participant->epointd);
+       fwp_contract_destroy(participant->service_contract);
+       //fwp_vres_destroy(participant->vresd);
+
+       /* Delete all participant's contracts */
+       for (contdata = fwp_contract_table_foreach_begin(&participant->contract_table);
+            contdata;
+            contdata = fwp_contract_table_foreach_next(&participant->contract_table, contdata)) {
+               fwp_contract_destroy(contdata);
+       }
+       fwp_contract_table_foreach_end(&participant->contract_table);
+
+       fwp_participant_delete(participant);
+                       
+       FWP_DEBUG("BYE nodeid = %d appid = %d\n", participant_id.node_id, 
+                       participant_id.app_id);
+       
+       return 0;       
+}
+
+int 
+fwp_mngr_contract_reserve(fwp_msgb_t *msgb, fwp_participant_id_t participant_id)
+{
+       fwp_participant_t *participant;
+       fwp_contract_data_t *contdata;
+
+       /* Find participant */
+       if (!(participant = fwp_participant_table_find(&participant_id))){
+               return -EPERM;
+       }
+
+       contdata = fwp_contract_data_new();
+       
+       /* Extract contract header */
+       fwp_msg_contracthdr_out(msgb->data, &contdata->id, &contdata->status);
+       fwp_msgb_pull(msgb, sizeof(struct fwp_msg_contracthdr));
+       /* Extract contract params */
+       fwp_msg_contract_out(msgb->data, &contdata->contract);
+       fwp_msgb_pull(msgb, sizeof(struct fwp_msg_contract));
+
+       /*launch admission test */
+       fwp_admctrl_test(contdata);             
+       
+       free(msgb);
+       msgb = fwp_msgb_alloc(sizeof(struct fwp_msg_header) +
+                                       sizeof(struct fwp_msg_contract) +
+                                       sizeof(struct fwp_msg_vres_params));
+       fwp_msgb_reserve(msgb,sizeof(struct fwp_msg_header));
+       
+       /*Add contract header*/
+       fwp_msg_contracthdr_in(msgb->tail, contdata->id, contdata->status);
+       fwp_msgb_put(msgb, sizeof(struct fwp_msg_contracthdr));
+       /* Add contract params */
+       /* No needed to send back if spare capacity is not considered
+        * fwp_msg_contract_in(msgb->tail, &contdata->contract);
+        * fwp_msgb_put(msgb, sizeof(struct fwp_msg_contract));
+        * */
+       
+       /*Send back contract reservation */
+       if (contdata->status == FWP_CONT_RESERVED) {
+               fwp_msg_vres_params_in(msgb->tail, &contdata->vres_params);
+               FWP_DEBUG("Sent vres params budget=%d period=%d ac=%d\n", 
+                               contdata->vres_params.budget,
+                               contdata->vres_params.period_usec,
+                               contdata->vres_params.ac_id);
+               fwp_msgb_put(msgb, sizeof(struct fwp_msg_vres_params));
+               /* Add contract to contract table */
+               fwp_contract_table_insert(&participant->contract_table,contdata);
+               FWP_DEBUG("Contract id=%d stored in table\n", contdata->id);
+
+       } else {
+               free(contdata);
+       }       
+       
+       fwp_mngt_send(FWP_MSG_RESERVE, msgb, 
+                       fwp_participant_this, participant);
+       return 0;
+}
+
+int 
+fwp_mngr_contract_commit(fwp_msgb_t *msgb, fwp_participant_id_t participant_id)
+{
+       fwp_participant_t *participant;
+       fwp_contract_data_t *contdata;
+       fwp_contract_id_t  id;
+       fwp_contract_status_t  status;
+
+       /* Find participant */
+       if (!(participant = fwp_participant_table_find(&participant_id))){
+               return -EPERM;
+       }
+
+       fwp_msg_contracthdr_out(msgb->data, &id, &status);
+       fwp_msgb_pull(msgb, sizeof(struct fwp_msg_contracthdr));
+       FWP_DEBUG("Contract id=%d to commit\n", id);
+       
+       contdata = fwp_contract_table_find(&participant->contract_table, id);
+       contdata->status = FWP_CONT_NEGOTIATED;
+
+       /* TODO: Send response to confirm reception */
+       
+       return 0;       
+}
+
+int 
+fwp_mngr_contract_cancel(fwp_msgb_t *msgb, fwp_participant_id_t participant_id)
+{
+       fwp_participant_t *participant;
+       fwp_contract_data_t *contdata;
+       fwp_contract_id_t  id;
+       fwp_contract_status_t  status;
+
+       /* Find participant */
+       if (!(participant = fwp_participant_table_find(&participant_id))){
+               return -EPERM;
+       }
+
+       fwp_msg_contracthdr_out(msgb->data, &id, &status);
+       fwp_msgb_pull(msgb, sizeof(struct fwp_msg_contracthdr));
+       
+       contdata = fwp_contract_table_find(&participant->contract_table, id);
+       contdata->status = FWP_CONT_NOTNEGOTIATED;
+       /* release vres - success only for local vres */
+       fwp_vres_destroy(contdata->vresd); 
+       /* delete contract from contract table */
+       fwp_contract_table_delete(&participant->contract_table, contdata);
+       fwp_contract_destroy(contdata);
+
+       /* Update admission data (only necessary for demo and GUI) */
+       fwp_admctrl_test(NULL);         
+       
+       FWP_DEBUG("Contract id=%d to canceled\n", id);
+               
+       return 0;       
+}
+
+void fwp_mngr_msg_handler(fwp_msgb_t *msgb)
+{
+       fwp_msg_type_t msg_type;
+       fwp_participant_id_t    participant_id;
+       int ret = 0;
+
+       fwp_msg_header_out(msgb->data, &msg_type, &participant_id);
+       fwp_msgb_pull(msgb, sizeof(struct fwp_msg_header));
+       
+       switch (msg_type) {
+               case  FWP_MSG_HELLO:
+                       FWP_DEBUG("Message HELLO received from nodeid = %d "
+                                 "appid = %d\n", participant_id.node_id, 
+                                       participant_id.app_id);
+                       ret = fwp_mngr_hello(msgb, participant_id);
+                       if (ret < 0) {
+                               ret = fwp_mngr_bye(msgb, participant_id);
+                               if (ret < 0) {
+                                       error(0, errno, "Cannot send bye");
+                               }
+                       }
+                       break;
+               
+               case  FWP_MSG_BYE:
+                       FWP_DEBUG("Message BYE received from nodeid = %d "
+                                 "appid = %d\n", participant_id.node_id, 
+                                       participant_id.app_id);
+                       fwp_mngr_bye(msgb, participant_id);
+                       break;
+
+
+               case  FWP_MSG_RESERVE: 
+                       FWP_DEBUG("Message RESERVE received from nodeid = %d " 
+                                 "appid = %d\n", participant_id.node_id, 
+                                       participant_id.app_id);
+                       fwp_mngr_contract_reserve(msgb, participant_id);
+                       break;
+
+               case  FWP_MSG_COMMIT: 
+                       FWP_DEBUG("Message COMMIT received from nodeid = %d "
+                                 "appid = %d\n", participant_id.node_id, 
+                                       participant_id.app_id);
+                       fwp_mngr_contract_commit(msgb, participant_id);
+                       break;  
+               
+               case  FWP_MSG_CANCEL: 
+                       FWP_DEBUG("Message CANCEL received from nodeid = %d "
+                                 "appid = %d\n", participant_id.node_id, 
+                                       participant_id.app_id);
+                       fwp_mngr_contract_cancel(msgb, participant_id);
+                       break;  
+               
+               default:
+                       printf("Invalid message\n.");
+                       fwp_msgb_free(msgb);
+       }
+}
+
+void fwp_mngr_main_loop()
+{
+       struct fwp_msgb *msgb;
+       int rv;
+
+       /* start admission control thread */
+       while (1 /*exit_flag*/){
+               //gui_print_status();
+               rv = fwp_mngr_input(&msgb);
+               if (rv == 0 && msgb)
+                       fwp_mngr_msg_handler(msgb);
+               FWP_DEBUG("Mngr waiting for next msg.\n");
+       }
+}
+
+int main()
+{
+       if (fwp_init()) {
+               fprintf(stderr,"FWP manager initialization failed.\n");
+               exit(1);
+       }
+
+       //gui_init();
+       fwp_mngr_main_loop();
+       //gui_end();
+       
+       return 0;       
+} 
diff --git a/src/fwp/fwp/old.mngr/fwp_participant_table.c b/src/fwp/fwp/old.mngr/fwp_participant_table.c
new file mode 100644 (file)
index 0000000..0b23a37
--- /dev/null
@@ -0,0 +1,90 @@
+#include "fwp_participant_table.h"
+#include <pthread.h>
+
+typedef
+struct {
+       unsigned int                    nr_participants;
+       /*gavl_cust_root_field_t        root;*/
+       gavl_node_t                     *participant_tree;
+       pthread_mutex_t                 lock;
+} fwp_participant_table_t;
+
+int fwp_cmp_participant_id(const void *a, const void *b)
+{
+  if (((fwp_participant_id_t*)a)->node_id > ((fwp_participant_id_t*)b)->node_id) 
+         return 1;
+  if (((fwp_participant_id_t*)a)->node_id < ((fwp_participant_id_t*)b)->node_id)
+         return -1;
+  
+  if (((fwp_participant_id_t*)a)->app_id > ((fwp_participant_id_t*)b)->app_id) 
+         return 1;
+  if (((fwp_participant_id_t*)a)->app_id < ((fwp_participant_id_t*)b)->app_id) 
+         return -1;
+  
+      return 0;
+}
+
+GAVL_CUST_NODE_INT_DEC(_fwp_participant_table, fwp_participant_table_t, 
+                       fwp_participant_t, fwp_participant_id_t, 
+                       participant_tree, participant_tree_node, id, 
+                       fwp_cmp_participant_id);
+
+GAVL_CUST_NODE_INT_IMP(_fwp_participant_table, fwp_participant_table_t, 
+                       fwp_participant_t, fwp_participant_id_t, 
+                       participant_tree, participant_tree_node, id, 
+                       fwp_cmp_participant_id);
+
+fwp_participant_table_t  fwp_participant_table = {
+               .nr_participants = 0,
+               .participant_tree = NULL,
+               .lock = PTHREAD_MUTEX_INITIALIZER,
+};
+
+int fwp_participant_table_nr_participants()
+{
+       return fwp_participant_table.nr_participants;
+}
+
+void fwp_participant_table_insert(fwp_participant_t *participant)
+{
+       pthread_mutex_lock(&fwp_participant_table.lock);
+       _fwp_participant_table_insert(&fwp_participant_table, participant);
+       fwp_participant_table.nr_participants++;
+       pthread_mutex_unlock(&fwp_participant_table.lock);
+}
+
+fwp_participant_t* 
+fwp_participant_table_find(fwp_participant_id_t *participant_id)
+{
+       return _fwp_participant_table_find(&fwp_participant_table, 
+                                               participant_id);
+}
+
+int fwp_participant_table_delete(fwp_participant_t *participant)
+{
+       int rv;
+
+       pthread_mutex_lock(&fwp_participant_table.lock);
+       rv = _fwp_participant_table_delete(&fwp_participant_table, participant); 
+       fwp_participant_table.nr_participants--;
+       pthread_mutex_unlock(&fwp_participant_table.lock);
+       
+       return rv;
+}
+
+fwp_participant_t* fwp_participant_table_foreach_begin(void)
+{
+       pthread_mutex_lock(&fwp_participant_table.lock);
+       return _fwp_participant_table_first(&fwp_participant_table);
+}
+
+void fwp_participant_table_foreach_end(void)
+{
+       pthread_mutex_unlock(&fwp_participant_table.lock);
+}
+
+fwp_participant_t* fwp_participant_table_foreach_next(fwp_participant_t *current)
+{
+       return _fwp_participant_table_next(&fwp_participant_table, current);
+}
+
diff --git a/src/fwp/fwp/old.mngr/fwp_participant_table.h b/src/fwp/fwp/old.mngr/fwp_participant_table.h
new file mode 100644 (file)
index 0000000..2c1a35a
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _FWP_PARTICIPANT_TABLE_H
+#define _FWP_PARTICIPANT_TABLE_H
+
+#include "fwp_participant.h"
+
+void fwp_participant_table_insert(fwp_participant_t *participant);
+fwp_participant_t* fwp_participant_table_find(fwp_participant_id_t *participant_id);
+int fwp_participant_table_delete(fwp_participant_t *participant);
+
+fwp_participant_t* fwp_participant_table_foreach_begin(void);
+fwp_participant_t* fwp_participant_table_foreach_next(fwp_participant_t *current);
+void              fwp_participant_table_foreach_end(void);
+
+int fwp_participant_table_nr_participants();
+
+#endif /*_FWP_PARTICIPANT_TABLE_H */
diff --git a/src/fwp/fwp/old.mngr/gui.c b/src/fwp/fwp/old.mngr/gui.c
new file mode 100644 (file)
index 0000000..6c9e190
--- /dev/null
@@ -0,0 +1,102 @@
+#include "gui.h"
+#include "fwp_foreach.h"
+#include <ncurses.h>
+#include <fwp_contract.h>
+#include "fwp_admctrl.h"
+
+void gui_init(void)
+{
+       initscr();
+       cbreak();
+       noecho();
+}
+
+static char *num_with_unit(char *buf, unsigned num, const char *units[])
+{
+       const int div[] = {100,10,1};
+       unsigned order = 0;
+       int d;
+
+       while (num > 999 && units[(order+3)/3] != NULL) {
+               num /= 10;
+               order++;
+       }
+
+       d = div[(order+2)%3];
+       if (d == 1)
+               sprintf(buf, "%4d %s", num, units[(order+2)/3]);
+       else
+               sprintf(buf, "%d.%.*d %s", num/d, (d==10) ? 1 : 2, num%d, units[(order+2)/3]);
+       return buf;
+}
+
+char *bandwidth_to_text(char *buf, unsigned bandwidth_bps)
+{
+       const char *unit[] = {"bps", "kbps", "Mbps", NULL};
+       return num_with_unit(buf, bandwidth_bps, unit);
+}
+
+char *usec_to_text(char *buf, unsigned usec)
+{
+       const char *unit[] = {"us", "ms", "s", NULL};
+       return num_with_unit(buf, usec, unit);
+}
+
+#define addfield(width, title, format, ...)                            \
+       move(y, x);                                                     \
+       x+=width;                                                       \
+       if (cd == NULL) addstr(title);                                  \
+       else {                                                          \
+               snprintf(str, sizeof(str), format, __VA_ARGS__);        \
+               addstr(str);                                            \
+       }
+
+static void print_contract(int y, fwp_contract_data_t *cd)
+{
+       const char *ac_ids[] = { [FWP_AC_VO]="VO", [FWP_AC_VI]="VI", [FWP_AC_BE]="BE", [FWP_AC_BK]="BK" };
+       struct fwp_contract *c = &cd->contract;
+       char str[200], s1[20];
+       int x = 0;
+       
+       addfield(4,  "ID", "%d", cd->id);
+       addfield(11, "BW", "%s", bandwidth_to_text(s1, (long long)1000*1000*8*c->budget/c->period_usec));
+       addfield(11, "Budget", "%d bytes", c->budget);
+       addfield(11, "Period", "%s", usec_to_text(s1, c->period_usec));
+       addfield(11, "Deadline", "%s", usec_to_text(s1, c->deadline_usec));
+       addfield(3,  "AC", "%s", ac_ids[cd->vres_params.ac_id]);
+       addfield(11, "Num partics", "%d", fwp_participant_table_nr_participants());
+}
+
+void gui_print_status()
+{
+       fwp_contract_data_t *cd;
+       struct foreach_contract fec;
+       int y;
+       char str[200];
+
+       clear();                /* Repaint the screen completely to
+                                * delete error messages */
+       mvaddstr(0, 0, "FWP Manager");
+       sprintf(str, "Reserved utilization: %d%%", fwp_reserved_utilization/100);
+       mvaddstr(2, 0, str);
+
+       /* Print header */
+       y=4;
+       print_contract(y, NULL);
+       y++;
+
+       /* Print contracts */
+       fec.contdata_new = NULL;
+       for (cd=foreach_contract_begin(&fec);
+            cd;
+            cd=foreach_contract_next(&fec)) {
+               print_contract(y, cd);
+               y++;
+       }
+       refresh();
+}
+
+void gui_end(void)
+{
+       endwin();
+}
diff --git a/src/fwp/fwp/old.mngr/gui.h b/src/fwp/fwp/old.mngr/gui.h
new file mode 100644 (file)
index 0000000..e2a9520
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef GUI_H
+#define GUI_H
+
+/* FIXME: Conditionally define these functions as empty macros (to
+ * disable GUI). */
+
+void gui_init(void);
+void gui_print_status(void);
+void gui_end(void);
+
+#endif
diff --git a/src/fwp/fwp/old.mngr/tests/BE_packet_size_graph b/src/fwp/fwp/old.mngr/tests/BE_packet_size_graph
new file mode 100644 (file)
index 0000000..0d81a2f
--- /dev/null
@@ -0,0 +1,62 @@
+12 17.5 17.5
+20 28.1 28.1
+30 40.2 40.2
+40 50.4 50.4
+50 60.0 60.0
+60 69.1 69.1
+70 77.2 77.2
+80 83.1 83.1
+90 89.8 89.8
+100 94.8 94.8
+110 102 102
+120 107 107
+130 111 111
+140 116 116
+150 119 119
+160 125 125
+170 126 126
+180 131 131
+190 132 132
+200 136 136
+250 151 151
+300 161 161
+350 168 168
+400 174 174
+450 179 179
+500 186 186
+550 187 187
+600 192 192
+650 194 194
+700 199 199
+750 200 200
+800 203 203
+850 204 204
+900 204 204
+950 205 205
+1000 208 208
+1050 207 207
+1100 210 210
+1150 210 210
+1200 212 212
+1250 214 214
+1300 212 212
+1350 217 217
+1400 215 215
+1450 217 217
+1460 212 212
+1470 217 217
+1480 199 199
+1490 200 200
+1500 199 199
+1510 199 199
+1520 198 198
+1550 200 200
+1600 201 201
+1650 204 204
+1700 205 205
+1750 207 207
+1800 207 207
+1850 206 206
+1900 209 209
+1950 211 211
+2000 210 210
diff --git a/src/fwp/fwp/old.mngr/tests/Makefile b/src/fwp/fwp/old.mngr/tests/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/old.mngr/tests/Makefile.omk b/src/fwp/fwp/old.mngr/tests/Makefile.omk
new file mode 100644 (file)
index 0000000..7c51521
--- /dev/null
@@ -0,0 +1,6 @@
+test_PROGRAMS = adm_utilization
+
+adm_utilization_SOURCES = adm_utilization.c ../admtest_utilization.c
+adm_utilization_LIBS = fwp
+
+CFLAGS=-Wall -O0 -g
diff --git a/src/fwp/fwp/old.mngr/tests/VI_packet_size_graph b/src/fwp/fwp/old.mngr/tests/VI_packet_size_graph
new file mode 100644 (file)
index 0000000..724dc98
--- /dev/null
@@ -0,0 +1,62 @@
+12 64.6 0.511
+20 45.6 2.04
+30 64.1 2.56
+40 80.5 1.66
+50 94.8 3.45
+60 98.0 28.1
+70 98.4 53.1
+80 98.9 73.9
+90 98.4 89.1
+100 98.9 102
+110 98.9 108
+120 98.8 119
+130 98.7 128
+140 98.9 130
+150 99.7 137
+160 99.4 141
+170 100 145
+180 98.1 153
+190 101 151
+200 99.6 152
+250 99.5 165
+300 100 176
+350 98.7 180
+400 99.8 187
+450 100 189
+500 100 191
+550 98.9 194
+600 100 193
+650 100 198
+700 99.8 199
+750 100 199
+800 99.9 200
+850 98.6 205
+900 99.1 207
+950 99.3 204
+1000 99.8 203
+1050 102 198
+1100 100 204
+1150 98.6 207
+1200 102 204
+1250 99.4 206
+1300 97.8 208
+1350 99.0 207
+1400 97.4 209
+1450 99.7 208
+1460 98.7 210
+1470 100 208
+1480 99.5 198
+1490 100 197
+1500 101 198
+1510 100 201
+1520 100 198
+1550 99.7 198
+1600 103 195
+1650 98.4 203
+1700 99.2 200
+1750 101 201
+1800 101 200
+1850 100 203
+1900 101 199
+1950 99.5 201
+2000 99.8 208
diff --git a/src/fwp/fwp/old.mngr/tests/VO_packet_size_graph b/src/fwp/fwp/old.mngr/tests/VO_packet_size_graph
new file mode 100644 (file)
index 0000000..e6b362d
--- /dev/null
@@ -0,0 +1,62 @@
+12 70.5 0.64
+20 63.1 2.81
+30 87.3 2.56
+40 98.2 0.896
+50 98.3 2.56
+60 98.5 27.9
+70 98.3 53.0
+80 99.4 71.0
+90 98.6 87.6
+100 99.6 97.1
+110 98.8 110
+120 99.2 118
+130 99.0 125
+140 99.1 134
+150 99.3 135
+160 99.7 141
+170 99.1 144
+180 99.0 150
+190 100 154
+200 100 154
+250 99.4 164
+300 99.4 178
+350 99.1 183
+400 99.3 187
+450 99.5 190
+500 100 193
+550 99.2 193
+600 99.5 194
+650 99.2 195
+700 100 198
+750 100 197
+800 99.8 199
+850 99.3 201
+900 100 204
+950 100 202
+1000 99.8 204
+1050 100 204
+1100 100 205
+1150 99.0 206
+1200 100 207
+1250 99.3 207
+1300 97.9 208
+1350 100 206
+1400 96.3 211
+1450 99.6 205
+1460 98.3 206
+1470 97.4 212
+1480 98.8 199
+1490 99.9 195
+1500 101 197
+1510 100 197
+1520 96.7 203
+1550 100 198
+1600 100 200
+1650 99.3 200
+1700 101 200
+1750 97.8 202
+1800 99.0 203
+1850 96.8 205
+1900 98.4 205
+1950 102 203
+2000 99.5 203
diff --git a/src/fwp/fwp/old.mngr/tests/adm_utilization.c b/src/fwp/fwp/old.mngr/tests/adm_utilization.c
new file mode 100644 (file)
index 0000000..797da81
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * @file   adm_utilization.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * 
+ * @brief  Test for utilization based admition control.
+ *
+ * This test tries to simulate results of the following test whose
+ * results are available at:
+ * http://rtime.felk.cvut.cz/frescor/images/b/bb/Packet_sizes_sat_comp.pdf
+ * (http://rtime.felk.cvut.cz/frescor/index.php/Experiments#Experiments_2008.2F01)
+ *
+ * Brief description of the test: Measuring of saturation bandwidth of
+ * AC_BE with respect to the size of packets in AC_VO, AC_VI and AC_BE
+ * itself. In this test we have generated the following streams AC_VO:
+ * 100 kbps, AC_VI: 100 kbps and AC_BE: 500 kbps (saturation). The
+ * streams, where the packet size was not changed was formed by
+ * packets of 800 bytes (UDP). The real bandwidth of AC_BE was
+ * measured.
+ */
+
+#include "../admtest.h"
+#include <fwp_ctable.h>
+#include <fwp_ac.h>
+#include <string.h>
+#include <fwp_utils.h>
+
+void insert_contract(struct fwp_ctable *ctable, enum ac_id_t ac, int bandwidth_bps, int packet_size)
+{
+       struct fwp_ctable_entry entry;
+       int period_usec;
+
+       if (bandwidth_bps == 0) return;
+       
+       period_usec = SEC_TO_USEC*packet_size*8/bandwidth_bps;
+
+       memset(&entry, 0, sizeof(entry));
+       entry.contract.budget = packet_size;
+       entry.contract.period_usec = period_usec;
+       entry.contract.ac_id = ac;
+
+       fwp_ctable_put(ctable, &entry);
+}
+
+int main()
+{
+       int ac, size;
+       struct fwp_ctable ctable;
+
+       for (ac=FWP_AC_VO; ac <= FWP_AC_BE; ac++) {
+               for (size=10; size < 2000; size+=10) {
+                       /* Find maximum BE badwidth by binary
+                        * chopping. */
+                       int min=0, max=500000, bw;
+                       int packet_size[] = {[FWP_AC_VO] = (ac == FWP_AC_VO) ? size : 800,
+                                            [FWP_AC_VI] = (ac == FWP_AC_VI) ? size : 800,
+                                            [FWP_AC_BE] = (ac == FWP_AC_BE) ? size : 800};
+                       enum contract_status_t cs;
+                       bw=(max+min+1)/2;
+                       while (min < max) {
+                               fwp_ctable_init(&ctable);
+
+                               /* Two equal contracts, one for each direction */
+                               insert_contract(&ctable, FWP_AC_VO, 100*Kbit, packet_size[FWP_AC_VO]);
+                               insert_contract(&ctable, FWP_AC_VO, 100*Kbit, packet_size[FWP_AC_VO]);
+
+                               insert_contract(&ctable, FWP_AC_VI, 100*Kbit, packet_size[FWP_AC_VI]);
+                               insert_contract(&ctable, FWP_AC_VI, 100*Kbit, packet_size[FWP_AC_VI]);
+                               
+                               insert_contract(&ctable, FWP_AC_BE, bw, packet_size[FWP_AC_BE]);
+                               insert_contract(&ctable, FWP_AC_BE, bw, packet_size[FWP_AC_BE]);
+                               cs = fwp_adm_test(&ctable);
+                               if (cs == FWP_CNT_REJECTED) {
+                                       max = bw-1;
+                               } else {
+                                       min = bw;
+                               }
+                               bw=(max+min+1)/2;
+                       }
+                       printf("%d %f\n", size, bw/1000.0);
+               }
+               printf("\n\n");
+       }
+       return 0;
+}
diff --git a/src/fwp/fwp/old.mngr/tests/plot b/src/fwp/fwp/old.mngr/tests/plot
new file mode 100755 (executable)
index 0000000..56e070c
--- /dev/null
@@ -0,0 +1 @@
+../../_compiled/bin-tests/adm_utilization > data && gnuplot plot_sat | ps2pdf - admutil_comp.pdf
diff --git a/src/fwp/fwp/old.mngr/tests/plot_sat b/src/fwp/fwp/old.mngr/tests/plot_sat
new file mode 100644 (file)
index 0000000..f7b072a
--- /dev/null
@@ -0,0 +1,22 @@
+# Usage: adm_utilization > data; gnuplot plot_sat|ps2pdf admutil_comp.pdf
+
+set terminal postscript color landscape
+#set output "admutil_comp.eps"
+
+set style line 1 lt 1 lc rgb "red"
+set style line 2 lt 1 lc rgb "green"
+set style line 3 lt 1 lc rgb "blue"
+
+set style data lines
+set grid
+set key right bottom nobox
+set title "Comparsion of utilization based test and reality"
+set xlabel "Packet sizes [bytes]"
+set ylabel "AC_BE bandwidth [kbps]"
+
+plot  "data" index 0 with lines lt 1 lw 3 lc rgb "red"   title "utilization test: AC_VO changed",\
+      "data" index 1 with lines lt 1 lw 3 lc rgb "green" title "utilization test: AC_VI changed",\
+      "data" index 2 with lines lt 1 lw 3 lc rgb "blue"  title "utilization test: AC_BE changed",\
+      "VO_packet_size_graph" using 1:3 with points lc rgb "red"   title "reality: AC_VO changed",\
+      "VI_packet_size_graph" using 1:3 with points lc rgb "green" title "reality: AC_VI changed",\
+      "BE_packet_size_graph" using 1:3 with points lc rgb "blue"  title "reality: AC_BE changed"
diff --git a/src/fwp/fwp/tests/Makefile b/src/fwp/fwp/tests/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/tests/Makefile.omk b/src/fwp/fwp/tests/Makefile.omk
new file mode 100644 (file)
index 0000000..05c9faa
--- /dev/null
@@ -0,0 +1,7 @@
+#SUBDIRS= fwp_msgtest fwp_vrestest 
+#fwp_prototest fwp_mngrtest  
+#CFLAGS += -Wall -D_REENTRANT -g
+#SUBDIRS= fwp_msgtest fwp_vrestest fwp_prototest fwp_mngrtest  
+#fwp_mngrtest unixsocktest
+
+SUBDIRS+=timing
diff --git a/src/fwp/fwp/tests/README b/src/fwp/fwp/tests/README
new file mode 100644 (file)
index 0000000..ec56f30
--- /dev/null
@@ -0,0 +1,8 @@
+fwp_msgtest - test of modules: fwp_msgb, fwp_msgq, fwp_msg
+#fwp_vrestest - test of modules: fwp_ac, fwp_vres
+fwp_prototest - test of modules: fwp_proto - sending and receiving data 
+               through vres
+fwp_fnatest - TODO: test of modules: fwp_fna
+
+unixsocktest - just for simple testing of unix socket behavioural
+hashtest- test for fwp_hashtable implemented in the future(maybe)
diff --git a/src/fwp/fwp/tests/fwp_mngrtest/Makefile b/src/fwp/fwp/tests/fwp_mngrtest/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/tests/fwp_mngrtest/Makefile.omk b/src/fwp/fwp/tests/fwp_mngrtest/Makefile.omk
new file mode 100644 (file)
index 0000000..a6f460c
--- /dev/null
@@ -0,0 +1,5 @@
+CFLAGS += -g
+
+test_PROGRAMS = fwp_mngrtest
+fwp_mngrtest_SOURCES+= fwp_mngrtest.c
+lib_LOADLIBES += fwp pthread rt ulut
diff --git a/src/fwp/fwp/tests/fwp_mngrtest/fwp_mngrtest.c b/src/fwp/fwp/tests/fwp_mngrtest/fwp_mngrtest.c
new file mode 100644 (file)
index 0000000..b5c4e60
--- /dev/null
@@ -0,0 +1,138 @@
+/**
+ * \file fwp_mngrtest.c
+ *
+ * This is a test application that:
+ * - connects to manager
+ * - negotiates contract
+ * - creates send endpoint and binds it to vres
+ * - sends and receives two messages Hello1 and Hello2
+ * - cancels contract
+ * - disconnects from manager
+ */
+
+#define CONFIGURE_MNGR_ADDR 127.0.0.1
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include <errno.h>
+#include <stdio.h>
+
+fwp_endpoint_attr_t  attr;
+
+void* receiver(void *arg)
+{
+       fwp_endpoint_d_t repoint_d1;
+       int i,len;
+       char buffer[30];
+
+       FWP_DEBUG("Creating receive endpoint\n");
+       if (fwp_receive_endpoint_create(7777, &attr,&repoint_d1) < 0){
+               perror("Error while creating receive endpoint\n");
+               return NULL;
+       }
+               
+       FWP_DEBUG("Receive endpoint created \n");
+       for (i = 0; i < 3; i++) {
+               if ((len = fwp_recv(repoint_d1, buffer, sizeof(buffer), 0)) < 0) {
+                       perror("Error while receiving data::");
+                       return NULL;
+               } else {
+                       printf("Received %s\n",buffer);
+                       //for (j = 0 ; j < 10; i++)
+                       //      printf("%c", buffer[i]);
+
+               }
+               printf("END\n");
+       }
+
+       return NULL;
+}
+
+int main()
+{
+       int i,rc,len; 
+       fwp_vres_d_t vres_d1, vres_d2, vres_d3;
+       fwp_contract_d_t cnt1d, cnt2d, cnt3d;
+       fwp_endpoint_d_t sepoint_d1, sepoint_d2, repoint_d1, repoint_d2;
+       char msg1[] = "Hello1";
+       char msg2[] = "Hello2";
+       fwp_contract_t cnt1;
+       fwp_contract_t cnt2;
+       fwp_contract_t cnt3;
+       pthread_t       id;
+       
+       cnt1.budget = 100;
+       cnt1.period_usec = 10000;
+
+       cnt2.budget = 120;
+       cnt2.period_usec = 1000;
+
+       cnt3.budget = 130;
+       cnt3.period_usec = 2000;
+       
+       printf("Start\n");
+       if (fwp_init() != 0) {
+               printf("fwp_init failed!\n");
+               return EXIT_FAILURE;
+       }       
+       
+       fwp_endpoint_attr_init(&attr);
+       fwp_endpoint_attr_setreliability(&attr, FWP_EPOINT_RELIABLE);
+       pthread_create(&id, NULL, &receiver, (void*) NULL);
+       
+       cnt1d = fwp_contract_create(&cnt1);
+       fwp_contract_negotiate(cnt1d, &vres_d1);
+       if (fwp_contract_is_negotiated(cnt1d)) {
+               printf("CONTRACT1 NEGOTIATED.\n");
+       }else 
+               printf("CONTRACT1 NOT NEGOTIATED.\n");
+
+/*     cnt2d = fwp_contract_create(&cnt2);
+       fwp_contract_negotiate(cnt2d, &vres_d2);
+       if (fwp_contract_is_negotiated(cnt2d)) {
+               printf("Contract2 negotiated.\n");
+       }else 
+               printf("Contract2 not negotiated.\n");
+       
+       cnt3d = fwp_contract_create(&cnt3);
+       fwp_contract_negotiate(cnt3d, &vres_d3);
+       if (fwp_contract_is_negotiated(cnt3d)) {
+               printf("Contract3 negotiated.\n");
+       }else 
+               printf("Contract3 not negotiated.\n");
+*/     
+       if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), 7777, 
+               &attr, &sepoint_d1) < 0) {
+               return EXIT_FAILURE;
+       }
+       printf("Send endpoint 1 created\n");
+       
+       if ((fwp_send_endpoint_bind(sepoint_d1, vres_d1)) != 0){
+               printf("Bind error\n");
+               return EXIT_FAILURE;
+       }
+
+       fwp_send(sepoint_d1, msg1, sizeof(msg1), 0);
+       printf("Sent msg 1\n");
+       fwp_send(sepoint_d1, msg2, sizeof(msg2), 0);
+       printf("Sent msg 2\n");
+
+       sleep(1);
+       fwp_contract_cancel(cnt1d);
+       printf("Contract 1 is CANCELED\n"); 
+       
+       if (fwp_send(sepoint_d1, msg2, sizeof(msg2), 0) < 0 ) {
+               printf("Failed to send message.\n");
+       }
+
+       if (fwp_contract_destroy(cnt1d) == 0) {
+               printf("Contract 1 is DESTROYED.\n");
+       }
+
+       fwp_mngt_disconnect();
+       
+       printf("Test PASSED!\n");
+       scanf("Press key");     
+
+       return EXIT_SUCCESS;
+}
diff --git a/src/fwp/fwp/tests/hashtest/hashtable.h b/src/fwp/fwp/tests/hashtest/hashtable.h
new file mode 100644 (file)
index 0000000..2ff971f
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef _HASHTABLE_H
+#define _HASHTABLE_H
+
+/* Zbyva nadefinovat iteraci pres zretazeny seznam 
+ *
+ *mozno vyheldavat zaznamu dle label
+ *
+ */
+
+#include "list.h"
+//#include "ul_list.h"
+#include <stdlib.h>
+
+/* Hash table with linked list per each entry*/
+struct hash_table {
+       struct list_head *entries;
+       unsigned int size;
+};
+
+static inline int htable_init(struct hash_table *htable, int size)
+{
+       int i;
+
+       void *entries = malloc(sizeof(struct list_head) * size);        
+       if (!entries)
+               return -1;
+
+       htable->entries = (struct list_head*) entries;
+       htable->size = size;
+       for ( i = 0; i < size; i++)
+               INIT_LIST_HEAD(&htable->entries[i]);
+
+       return 0;
+}
+
+static inline void htable_free(struct hash_table *htable)
+{      
+       free(htable->entries);
+       htable->entries = NULL;
+       htable->size = 0;
+}
+
+
+static inline void htable_add(struct hash_table *htable, unsigned int hash,
+                             struct list_head *new)
+{
+       __list_add(new, htable->entries[hash].prev, &htable->entries[hash]);
+}
+
+
+static inline void htable_del(struct hash_table *htable, unsigned int hash,
+                             struct list_head *new)
+{
+       __list_add(new, htable->entries[hash].prev, &htable->entries[hash]);
+}
+
+
+#endif /* _HASHTABLE_H */
diff --git a/src/fwp/fwp/tests/hashtest/hashtest.c b/src/fwp/fwp/tests/hashtest/hashtest.c
new file mode 100644 (file)
index 0000000..fe91dc0
--- /dev/null
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include "list.h"
+#include "hashtable.h"
+#include <string.h>
+
+
+#define MAX_CHARS 48
+
+struct item {
+       struct list_head node;
+       int value;
+       char label[MAX_CHARS];
+};
+
+unsigned int hash_func(char *key, unsigned int modulus) 
+{
+       unsigned int hash = 0;
+       int i;
+       
+       // loop while max_chars is not reached and a null character is not found
+       for (i=0; i < MAX_CHARS && key[i]!=0; i++) {
+              hash = (hash*37+ key[i]);
+       }
+       
+       return (hash % modulus);
+}
+
+
+int main()
+{
+       struct hash_table htable;
+       struct item a,c;
+       //struct item a = {{NULL, NULL}, 5, "FRESCOR"};
+       //struct item c = {{NULL, NULL}, 100, "FRSH"};
+       
+       unsigned int hash;
+
+       INIT_LIST_HEAD(&a.node);
+       a.value = 5;
+       strcpy(a.label,"FRESCOR");
+       
+       INIT_LIST_HEAD(&c.node);
+       c.value = 100;
+       strcpy(c.label,"FRSH");
+       
+       htable_init(&htable, 5);
+       
+       hash = hash_func(a.label, htable.size);
+       printf("hash(a) = %d\n", hash); 
+       htable_add(&htable, hash, &a.node);
+
+       hash = hash_func(c.label, htable.size);
+       printf("hash(b) = %d\n", hash); 
+       htable_add(&htable, hash, &c.node);
+       
+       htable_free(&htable);
+
+       return 0;
+}
diff --git a/src/fwp/fwp/tests/timing/Makefile b/src/fwp/fwp/tests/timing/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/tests/timing/Makefile.omk b/src/fwp/fwp/tests/timing/Makefile.omk
new file mode 100644 (file)
index 0000000..57aac08
--- /dev/null
@@ -0,0 +1,3 @@
+test_PROGRAMS = fwp-timing
+fwp-timing_SOURCES = fwp-timing.c
+lib_LOADLIBES = frsh
diff --git a/src/fwp/fwp/tests/timing/fwp-timing.c b/src/fwp/fwp/tests/timing/fwp-timing.c
new file mode 100644 (file)
index 0000000..4ed0c28
--- /dev/null
@@ -0,0 +1,553 @@
+/*
+ * A tool for measuring FWP latency. This program aims to be simpler
+ * than wme_test and is intended to be run on a single machine with
+ * multiple wifi interfaces and send-to-self kernel patch applied.
+ *
+ * This program creates both sides of communication and measures the
+ * communication delays.
+ */
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <frsh.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <fwp_res.h>
+#include <error.h>
+#include <sys/mman.h>
+#include <semaphore.h>
+#include <ul_logreg.h>
+
+bool opt_verbose = false;
+bool opt_quiet = false;
+
+#define HIST_MAX_US 10000000
+#define HIST_RES_US 10
+
+struct histogram {
+       unsigned cnt[(HIST_MAX_US+1)/HIST_RES_US];
+       unsigned max;
+};
+
+/* static void hist_init(struct histogram *h) */
+/* { */
+/*     memset(h, 0, sizeof(*h)); */
+/* } */
+
+static void hist_add(struct histogram *h, int us)
+{
+       assert(us > 0);
+       if (us > HIST_MAX_US)
+               us = HIST_MAX_US;
+       __sync_fetch_and_add(&h->cnt[us/HIST_RES_US], 1);
+
+       unsigned max;
+       do {
+               max = h->max;
+       } while (us > max && ! __sync_bool_compare_and_swap(&h->max, max, us));
+               
+}
+
+static unsigned hist_get_percentile(struct histogram *h, unsigned p)
+{
+       uint64_t sum = 0, psum;
+       int i;
+       for (i=0; i<(HIST_MAX_US+1)/HIST_RES_US; i++)
+               sum += h->cnt[i];
+
+       psum = sum * p / 100;
+       sum = 0;
+       for (i=0; i<(HIST_MAX_US+1)/HIST_RES_US; i++) {
+               sum += h->cnt[i];
+               if (sum >= psum)
+                       break;
+       }
+       return i*HIST_RES_US;
+}
+
+struct stats {
+       uint32_t sent;
+       uint32_t received;
+       uint32_t lost;
+} stats;
+
+struct histogram hist;
+
+void set_rt_prio(int priority)
+{
+       int maxpri, minpri;
+       static struct sched_param param;
+
+       if ((maxpri = sched_get_priority_max(SCHED_FIFO)) == -1)        {
+               fprintf(stderr, "warning: sched_get_priority_max failed\n");
+       }
+
+       if ((minpri = sched_get_priority_min(SCHED_FIFO)) == -1)        {
+               fprintf(stderr, "warning: sched_get_priority_min failed\n");
+       }
+
+       if (priority > maxpri)  {
+               fprintf(stderr, "warning: maximum priority allowed is %d.\n", maxpri);
+       }
+       if (priority < minpri)  {
+               fprintf(stderr, "warning: minimum priority allowed is %d.\n", minpri);
+       }
+
+       param.sched_priority = priority;
+
+       if (sched_setscheduler(0, SCHED_FIFO, &param) == -1)    {
+               fprintf(stderr, "warning: sched_setscheduler failed\n");
+       }
+
+       mlockall(MCL_CURRENT | MCL_FUTURE);
+}
+
+struct stream_params {
+       int budget;
+       int period_ms;
+       bool async;
+       struct in_addr src, dst;
+       int number;
+       int id;
+       int count;
+       frsh_vres_id_t vres;
+       pthread_t thread;
+       int jitter;
+};
+
+
+int negotiate_contract(struct stream_params *p)
+{
+       frsh_contract_t contract;
+       int ret;
+       frsh_rel_time_t period;
+       frsh_rel_time_t budget;
+       frsh_rel_time_t deadline;
+       fres_block_fwp *fwp;    
+       
+       ret = frsh_contract_init(&contract);
+       if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+       ret = frsh_contract_set_resource_and_label(
+               &contract,
+               FRSH_RT_NETWORK, FRSH_NETPF_FWP,
+               NULL);
+       if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+       frsh_network_bytes_to_budget(FRSH_NETPF_FWP, p->budget, &budget);
+       period = fosa_msec_to_rel_time(p->period_ms);
+       ret = frsh_contract_set_basic_params(&contract,
+                                            &budget,
+                                            &period,
+                                            FRSH_WT_BOUNDED,
+                                            FRSH_CT_REGULAR);
+       if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+
+
+       /* FWP doesn't accept smaller deadlines than 30 ms. */
+       if (frsh_rel_time_smaller(period, frsh_msec_to_rel_time(30)))
+               deadline = frsh_msec_to_rel_time(30);
+       else
+               deadline = period;
+       ret = frsh_contract_set_timing_reqs(&contract, false, &deadline);
+       if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_timing_reqs");
+
+       fwp = malloc(sizeof(*fwp));
+       if (!fwp) PERROR_AND_EXIT(errno, "malloc");
+       fwp->src = p->src.s_addr;
+       ret = fres_contract_add_fwp(contract, fwp);
+       if (ret) PERROR_AND_EXIT(ret, "fres_contract_add_fwp");
+
+       ret = frsh_contract_negotiate(&contract, &p->vres);
+
+       frsh_contract_destroy(&contract);
+
+       return ret;
+}
+
+void create_endpoints(struct stream_params *p,
+                     frsh_send_endpoint_t *epsrc,
+                     frsh_receive_endpoint_t *epdst)
+{
+       int ret;
+       frsh_send_endpoint_protocol_info_t    spi = { NULL, 0 };
+       frsh_receive_endpoint_protocol_info_t rpi = { NULL, 0 };
+       frsh_endpoint_queueing_info_t qi = { .queue_size=0,
+                                            .queue_policy=FRSH_QRP_OLDEST };
+
+       ret = frsh_receive_endpoint_create(FRSH_NETPF_FWP, 0, qi, rpi,
+                                          epdst);
+       if (ret != 0) error(1, errno, "fwp_receive_endpoint_create");
+               
+       unsigned int port;
+       frsh_receive_endpoint_get_params(*epdst, NULL, &port, NULL, NULL);
+
+       ret = frsh_send_endpoint_create(FRSH_NETPF_FWP,
+                                       p->dst.s_addr, port, spi,
+                                       epsrc);
+       if (ret < 0) error(1, errno, "frsh_send_endpoint_create()");
+               
+       ret = frsh_send_endpoint_bind(p->vres, *epsrc);
+       if (ret != 0) error(1, errno, "frsh_send_endpoint_bind");
+}
+
+
+static struct option long_opts[] = {
+    { "loglevel",required_argument, 0, 'l' },
+    { "period", required_argument, 0, 'p' },
+    { "budget", required_argument, 0, 'b' },
+    { "source", required_argument, 0, 's' },
+    { "dest",  required_argument, 0, 'd' },
+    { "async",         no_argument,       0, 'a' },
+    { "number",        required_argument, 0, 'n' },
+    { "count", required_argument, 0, 'c' },
+    { "verbose",no_argument,      0, 'v' },
+    { "quiet",  no_argument,      0, 'q' },
+    { "jitter", required_argument, 0, 'j' },
+    { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+       printf("usage: fwp-timing [ options ]\n");
+       printf("  -l, --loglevel <number>|<domain>=<number>,...\n");
+       printf("  -p, --period <ms>  period in miliseconds\n");
+       printf("  -b, --budget <bytes>  how many bytes is sent in each period\n");
+       printf("  -s, --source <ip>  source IP address\n");
+       printf("  -d, --dest <ip:port> destination IP address and port\n");
+       printf("  -a, --async  Send packets asynchronously\n");
+       printf("  -n, --number Number of streams with the same parameters\n");
+       printf("  -c, --count Number of messages to send [infinity]\n");
+       printf("  -q, --quiet Print only final statistics\n");
+       printf("  -/, --stream  New stream separator\n");
+       printf("  -v, --verbose Be more verbose\n");
+       printf("  -j, --jitter <percent> Sent jitter given as percentage of period\n");
+}
+
+int parse_opts(int *argc, char **argv[], struct stream_params *p)
+{
+       int opt;
+       int ret;
+       bool options_found = false;
+
+       while ((opt = getopt_long(*argc, *argv, "/ab:c:d:j:l:n:p:qs:v", long_opts, NULL)) != -1) {
+               options_found = true;
+               switch (opt) {
+               case 'a':
+                       p->async = true;
+                       break;
+               case 'b':
+                       p->budget = atoi(optarg);
+                       break;
+               case 'c':
+                       p->count = atoi(optarg);
+                       break;
+               case 'd':
+                       ret = inet_aton(optarg, &p->dst);
+                       if (!ret) {
+                               fprintf(stderr, "Destination IP address not recognized: %s\n",
+                                       optarg);
+                               usage();
+                               exit(1);
+                       }
+                       break;
+               case 'j':
+                       p->jitter = atoi(optarg);
+                       break;
+               case 'l':
+                       ul_log_domain_arg2levels(optarg);
+                       break;
+               case 'n':
+                       p->number = atoi(optarg);
+                       break;
+               case 'p':
+                       p->period_ms = atoi(optarg);
+                       break;
+               case 's':
+                       ret = inet_aton(optarg, &p->src);
+                       if (!ret) {
+                               fprintf(stderr, "Source IP address not recognized: %s\n",
+                                       optarg);
+                               usage();
+                               exit(1);
+                       }
+                       break;
+               case 'v':
+                       opt_verbose = true;
+                       break;
+               case 'q':
+                       opt_quiet = true;
+                       break;
+               case '/':
+                       break;
+               default:
+                       usage();
+                       exit(1);
+               }
+               if (opt == '/')
+                       break; 
+       }
+       return (options_found) ? 0 : -1;
+}
+
+volatile bool exit_flag = false;
+
+void stopper()
+{
+       exit_flag = true;
+}
+
+int
+timespec_subtract (result, x, y)
+     struct timespec *result, *x, *y;
+{
+  /* Perform the carry for the later subtraction by updating Y. */
+  if (x->tv_nsec < y->tv_nsec) {
+    int nsec = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1;
+    y->tv_nsec -= 1000000000 * nsec;
+    y->tv_sec += nsec;
+  }
+  if (x->tv_nsec - y->tv_nsec > 1000000000) {
+    int nsec = (x->tv_nsec - y->tv_nsec) / 1000000000;
+    y->tv_nsec += 1000000000 * nsec;
+    y->tv_sec -= nsec;
+  }
+
+  /* Compute the time remaining to wait.
+     `tv_nsec' is certainly positive. */
+  result->tv_sec = x->tv_sec - y->tv_sec;
+  result->tv_nsec = x->tv_nsec - y->tv_nsec;
+
+  /* Return 1 if result is negative. */
+  return x->tv_sec < y->tv_sec;
+}
+
+static inline double ts2d(struct timespec *ts)
+{
+       return ts->tv_sec + 1e-9*ts->tv_nsec;
+}
+
+static inline double tsdiff2d(struct timespec *x,
+                             struct timespec *y)
+{
+       struct timespec r;
+       timespec_subtract(&r, x, y);
+       return ts2d(&r);
+}
+
+static inline int tsdiff2us(struct timespec *x,
+                             struct timespec *y)
+{
+       struct timespec r;
+       timespec_subtract(&r, x, y);
+       return r.tv_sec*1000000 + r.tv_nsec/1000;
+}
+
+struct msg {
+       int cnt;
+       struct timespec ts;
+};
+
+struct receiver_params {
+       int budget;
+       frsh_receive_endpoint_t epdst;
+       int id;
+};
+
+void *receiver(void *arg)
+{
+       struct receiver_params *rp = arg;
+       frsh_receive_endpoint_t epdst = rp->epdst;
+       size_t mlen;
+       int ret;
+       int last_cnt = -1;
+       struct timespec tss, tsr;
+       struct msg *msg;
+       msg = malloc(rp->budget);
+       if (!msg) error(1, errno, "malloc msg");
+
+       while (!exit_flag) {
+               ret = frsh_receive_sync(epdst, msg, rp->budget, &mlen, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &tsr);
+               tss = msg->ts;
+               if (msg->cnt != last_cnt+1) {
+                       if (!opt_quiet)
+                               printf("%3d: packet(s) lost!\n", rp->id);
+                       __sync_fetch_and_add(&stats.lost, msg->cnt - last_cnt+1);
+               } else {
+                       hist_add(&hist, tsdiff2us(&tsr, &tss));
+                       __sync_fetch_and_add(&stats.received, 1);
+               }
+               if (opt_verbose)
+                       printf("%3d: %10d: %10.3lf ms\n",
+                              rp->id, msg->cnt, tsdiff2d(&tsr, &tss)*1000);
+               last_cnt = msg->cnt;
+       }
+       free(rp);
+       return NULL;
+}
+
+sem_t finished;
+
+void *sender(void *arg)
+{
+       struct stream_params *p = arg;
+       frsh_send_endpoint_t epsrc;
+       struct receiver_params *rp;
+       int ret;
+       struct msg *msg;
+       long int cnt=0;
+       pthread_t receiver_id;
+
+       msg = malloc(p->budget);
+       if (!msg) error(1, errno, "malloc msg");
+
+       rp = malloc(sizeof(*rp));
+       rp->budget = p->budget;
+       rp->id = p->id;
+       
+       create_endpoints(p, &epsrc, &rp->epdst);
+               
+       set_rt_prio(50);
+
+       ret = pthread_create(&receiver_id, NULL, receiver, rp);
+       
+       struct timespec next_period;
+       struct timespec tss;
+       clock_gettime(CLOCK_MONOTONIC, &next_period);
+       while (!exit_flag && (p->count == -1 || p->count--)) {
+               clock_gettime(CLOCK_MONOTONIC, &tss);
+               msg->cnt = cnt++;
+               msg->ts = tss;
+               if (p->async)
+                       ret = frsh_send_async(epsrc, msg, p->budget);
+               else {
+                       ret = frsh_send_sync(epsrc, msg, p->budget);
+                       clock_gettime(CLOCK_MONOTONIC, &next_period);
+               }
+               __sync_fetch_and_add(&stats.sent, 1);
+
+               int delay_ms;
+               if (p->jitter)
+                       delay_ms = p->period_ms*(100-p->jitter)/100
+                               + rand() % (2*p->period_ms*p->jitter/100);
+               else
+                       delay_ms = p->period_ms;
+
+               next_period.tv_sec  += (delay_ms/1000);
+               next_period.tv_nsec += (delay_ms%1000) * 1000000;
+               if (next_period.tv_nsec >= 1000000000) {
+                       next_period.tv_nsec -= 1000000000;
+                       next_period.tv_sec++;
+               }
+               clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
+                               &next_period, NULL);
+       }
+
+       
+       sem_post(&finished);
+       return NULL;
+}
+
+void print_stat(bool final)
+{
+       printf("Sent: %5d  Received: %5d  Lost: %5d Max: %8.3f ms",
+              stats.sent, stats.received, stats.lost, hist.max/1000.0);
+       if (final) {
+               printf("  Packetloss: %7.3f %%  95%%: %8.3f ms  99%%: %8.3f ms\n",
+                      100.0*stats.lost/stats.sent,
+                      hist_get_percentile(&hist, 95)/1000.0,
+                      hist_get_percentile(&hist, 99)/1000.0);
+       }
+       else
+               printf("\r");
+       fflush(stdout);
+}
+
+int main(int argc, char *argv[])
+{
+       int ret;
+       int i;
+       int num = 0;
+       bool negotiation_failure = false;
+       
+       struct stream_params sp = {
+               .budget = 1024,
+               .period_ms = 20,
+               .async = false,
+               .src.s_addr = htonl(INADDR_LOOPBACK),
+               .dst.s_addr = htonl(INADDR_LOOPBACK),
+               .number = 1,
+               .count = -1,
+       };
+       struct stream_params *p[100];
+
+       memset(p, 0, sizeof(p));
+
+       if (signal(SIGTERM, stopper) == SIG_ERR)
+               error(1, errno, "Error in signal registration");
+       if (signal(SIGINT, stopper) == SIG_ERR)
+               error(1, errno, "Signal handler registration error");
+
+       sem_init(&finished, 0, 0);
+       
+       ret = frsh_init();
+       if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+       
+       do {
+               ret = parse_opts(&argc, &argv, &sp);
+               if (num == 0 || ret == 0) {
+                       for (i=0; i<sp.number; i++) {
+                               p[num] = malloc(sizeof(*p[0]));
+                               if (!p[num]) error(1, errno, "malloc");
+                               *p[num] = sp;
+                               p[num]->id = num;
+                               ret = negotiate_contract(p[num]);
+                               if (!ret)
+                                       num++;
+                               else {
+                                       PERROR_FRESCOR(ret, "frsh_contract_negotiate");
+                                       free(p[num]);
+                                       negotiation_failure = true;
+                                       break;
+                               }
+                       }
+               }
+       } while(ret == 0);
+
+       if (negotiation_failure) {
+               goto destroy;
+       }
+
+       for (i=0; i<num; i++)
+               pthread_create(&p[i]->thread, NULL, sender, p[i]);
+
+       while (!exit_flag && !opt_quiet) {
+               int v;
+               print_stat(false);
+               sem_getvalue(&finished, &v);
+               if (v == num)
+                       break;
+               usleep(100000);
+       }
+
+       for (i=0; i<num; i++)
+               pthread_join(p[i]->thread, NULL);
+destroy:
+       for (i=0; i<num; i++) {
+               frsh_contract_cancel(p[i]->vres);
+               free(p[i]);
+       }
+
+       stats.lost = stats.sent - stats.received;
+       print_stat(true);
+       
+       return negotiation_failure ? 1 : 0;
+}
diff --git a/src/fwp/fwp/tests/timing/fwp-timing.gnuplot b/src/fwp/fwp/tests/timing/fwp-timing.gnuplot
new file mode 100644 (file)
index 0000000..c61d85c
--- /dev/null
@@ -0,0 +1,13 @@
+set key top left
+set xlabel "Number of simultaneous streams"
+set ylabel "Time [ms]
+set yrange [0:]
+set y2range [0:100]
+set y2label "Packet loss [%]
+set y2tics
+set grid
+
+plot "./fwp-timing.dat" using 1:2 title "Maximal delay [ms]" with lp,\
+     "./fwp-timing.dat" using 1:4 title "95th percentile [ms]" with lp,\
+     "./fwp-timing.dat" using 1:5 title "99th percentile [ms]" with lp,\
+     "./fwp-timing.dat" using 1:3 title "Packet loss [%]" with lp axis x1y2
diff --git a/src/fwp/fwp/tests/timing/fwp-timing.pl b/src/fwp/fwp/tests/timing/fwp-timing.pl
new file mode 100755 (executable)
index 0000000..009c72c
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/bin/perl -w
+
+$omk_rules_dir=qx'
+old_pwd=""
+while [ ! -e Makefile.rules ]; do
+       if [ "$old_pwd" = `pwd`  ]; then 
+              echo "Makefile.rules has not been found in this or parent directory" >&2; exit 1; 
+       else
+              old_pwd=`pwd`; 
+              cd -L .. 2>/dev/null; 
+       fi; 
+done;
+pwd';
+chomp $omk_rules_dir;
+
+sub catch_zap {
+    my $signame = shift;
+    die "Somebody sent me a SIG$signame";
+}
+$SIG{INT} = \&catch_zap;
+$SIG{TERM} = \&catch_zap;
+
+@srcdst = (
+    "-s 192.168.1.10 -d 192.168.1.11",
+    "-s 192.168.1.11 -d 192.168.1.12",
+    "-s 192.168.1.12 -d 192.168.1.13",
+    "-s 192.168.1.13 -d 192.168.1.10",
+);
+
+$max=10;
+$max=$ARGV[0] if (scalar(@ARGV));
+my @results=();
+for($i=1; $i<=$max; $i++) {
+    $|++;                      # Autoflush
+    printf "%3d: ", $i;
+    $|--;
+    my @streams = ();
+    for ($j=0; $j<@srcdst; $j++) {
+       use integer;
+       my $n = ($i-1) / @srcdst + ((($j % @srcdst) <= (($i-1) % @srcdst))  ? 1 : 0);
+       $streams[$j] = $srcdst[$j]." -n $n" if ($n);
+    }
+    $cmd="$omk_rules_dir/_compiled/bin-tests/fwp-timing -l 2 -q -c 1000 ".join(" -/ ", @streams);
+    #print "$cmd\n";
+    $out=`$cmd`;
+    print $out;
+    my @result;
+    if ($? == 0) {
+       @result = $out =~ /Max: *([0-9.]+).*Packetloss: *([0-9.]+).*95%: *([0-9.]+).*99%: *([0-9.]+)/;
+    } else {
+       @result = ();
+    }
+    $results[$i] = \@result;
+}
+
+# Print data for gnuplot
+open(DAT, ">", "fwp-timing.dat");
+for($i=1; $i<=$max; $i++) {
+    my $line = "$i ".join(" ", @{$results[$i]})."\n";
+    print DAT $line;
+}
+close DAT;
diff --git a/src/fwp/fwp/tests/unixsocktest/Makefile b/src/fwp/fwp/tests/unixsocktest/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/src/fwp/fwp/tests/unixsocktest/Makefile.omk b/src/fwp/fwp/tests/unixsocktest/Makefile.omk
new file mode 100644 (file)
index 0000000..ab32950
--- /dev/null
@@ -0,0 +1,18 @@
+CFLAGS += -Wall -D_REENTRANT -g
+
+test_PROGRAMS = unixclient unixclient_thread unixclient_thread_dgram unixserver\
+               unixserver_dgram
+
+unixclient_SOURCES+= unixclient.c 
+unixclient_thread_SOURCES+= unixclient_thread.c 
+unixclient_thread_dgram_SOURCES+= unixclient_thread_dgram.c 
+unixserver_SOURCES+= unixserver.c
+unixserver_dgram_SOURCES+= unixserver_dgram.c
+lib_LOADLIBES += fwp pthread 
+
+#utils_PROGRAMS = hashtest
+
+#lib_LIBRARIES = 
+
+#include_HEADERS = ../libfwp/include/list.h ../libfwp/include/hashtable.h 
+
diff --git a/src/fwp/fwp/tests/unixsocktest/unixclient.c b/src/fwp/fwp/tests/unixsocktest/unixclient.c
new file mode 100644 (file)
index 0000000..0224156
--- /dev/null
@@ -0,0 +1,71 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define SOCKET_PATH_SERVER "server_socket"
+
+int main(int argc, char *argv[])
+{
+       int sockfd;
+       struct sockaddr_un server_addr;
+       int result;
+       char msg[20];
+       char buf[20];
+       unsigned int msglen;
+       
+       if (argc < 2) {
+               printf("%s: Missing string parameter\n",argv[0]);
+               return -1;
+       }
+
+       msglen = strlen(argv[1]) + 1;
+       //printf("msg= %lu \n", sizeof(msg));
+
+       if (msglen > sizeof(msg))
+               msglen = sizeof(msg);
+
+       strncpy(msg, argv[1], msglen);
+
+       /*  Create a socket for the client.  */
+
+       sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+
+       /*  Name the socket, as agreed with the server.  */
+
+       server_addr.sun_family = AF_UNIX;
+       strcpy(server_addr.sun_path, SOCKET_PATH_SERVER);
+       
+       /*  Now connect our socket to the server's socket.  */
+
+       result = connect(sockfd, (struct sockaddr *)&server_addr,
+                        sizeof(server_addr));
+
+       if(result == -1) {
+               return -1;
+       }
+
+       while (1) {
+               while (send(sockfd, msg, msglen, 0) == -1){
+                       if (errno == EINTR) continue;
+                       goto out_err;
+               }
+               
+               while (recv(sockfd, buf, sizeof(buf),0) == -1){
+                       if (errno == EINTR) continue;
+                       goto out_err;           
+               }       
+       
+               printf("sent=%s received=%s\n", msg,buf);
+       }       
+
+       unlink(SOCKET_PATH_SERVER);
+       close(sockfd);
+       return 0;
+out_err:
+       unlink(SOCKET_PATH_SERVER);
+       close(sockfd);
+       return -1;      
+}
diff --git a/src/fwp/fwp/tests/unixsocktest/unixclient_thread.c b/src/fwp/fwp/tests/unixsocktest/unixclient_thread.c
new file mode 100644 (file)
index 0000000..b340dea
--- /dev/null
@@ -0,0 +1,82 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+
+void* messenger(void* arg)
+{
+       struct sockaddr_un server_addr;
+       int result;
+       char buf[20];
+       char *msg;
+       int sockfd;
+       unsigned int msglen;
+
+       msg = (char*) arg;
+       msglen = strlen(msg) + 1;
+       //printf("msg=%lu \n", sizeof(msg));
+
+       /*  Create a socket for the client.  */
+
+       sockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+
+       /*  Name the socket, as agreed with the server.  */
+
+       server_addr.sun_family = AF_UNIX;
+       strcpy(server_addr.sun_path, "server_socket");
+       
+       /*  Now connect our socket to the server's socket.  */
+
+       result = connect(sockfd, (struct sockaddr *)&server_addr,
+                        sizeof(server_addr));
+
+       if(result == -1) {
+               return NULL;
+       }
+
+       /*  We can now read/write via sockfd.  */
+       while (1) {
+               while (send(sockfd, msg, msglen, 0) == -1){
+                       if (errno == EINTR) continue;
+                       goto out_err;
+               }
+               
+               while (recv(sockfd, buf, sizeof(buf),0) == -1){
+                       if (errno == EINTR) continue;
+                       goto out_err;           
+               }       
+       
+               printf("sent=%s received=%s", msg,buf);
+               if (!strcmp(msg,buf)) 
+                       printf(" -- OK\n");
+               else
+                       printf(" -- FAILED!!!\n");
+       }       
+
+       close(sockfd);
+       return NULL;
+out_err:
+       close(sockfd);
+       return NULL;    
+}
+
+
+
+int main(int argc, char *argv[])
+{
+       char msg1[20]="Thread1";
+       char msg2[20]="Thread2";
+       pthread_attr_t attr;
+       pthread_t thread;
+               
+       pthread_attr_init(&attr);
+       pthread_create(&thread, &attr, messenger, (void*) msg1);
+       pthread_create(&thread, &attr, messenger, (void*) msg2);
+
+       while (1) { /* primitive wait but enough ;-) */
+               sleep(100000);
+       }
+}      
diff --git a/src/fwp/fwp/tests/unixsocktest/unixclient_thread_dgram.c b/src/fwp/fwp/tests/unixsocktest/unixclient_thread_dgram.c
new file mode 100644 (file)
index 0000000..e524861
--- /dev/null
@@ -0,0 +1,93 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+
+#define SOCKET_PATH_CLIENT "client_socket"
+#define SOCKET_PATH_SERVER "server_socket"
+
+void* messenger(void* arg)
+{
+       struct sockaddr_un server_addr;
+       struct sockaddr_un client_addr;
+       char buf[20];
+       char *msg;
+       int sockfd;
+       unsigned int msglen;
+       socklen_t server_addr_len;
+
+       msg = (char*) arg;
+       msglen = strlen(msg) + 1;
+       //printf("msg=%lu \n", sizeof(msg));
+
+       sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
+
+       bzero(&client_addr, sizeof(client_addr));
+       client_addr.sun_family = AF_UNIX;
+       strcpy(client_addr.sun_path, SOCKET_PATH_CLIENT);
+       
+//     unlink(SOCKET_PATH_CLIENT);
+
+       if (bind(sockfd,(struct sockaddr*)&client_addr, 
+                sizeof(client_addr)) < 0) {
+                       fprintf(stderr,"Client--bind");
+                       goto out_err;
+       }       
+
+       bzero(&server_addr, sizeof(server_addr));
+       server_addr.sun_family = AF_UNIX;
+       strcpy(server_addr.sun_path, SOCKET_PATH_SERVER);
+       
+       while (1) {
+               while (sendto(sockfd, msg, msglen, 0, 
+                             (struct sockaddr*)&server_addr, 
+                             sizeof(server_addr)) == -1){
+                       if (errno == EINTR) continue;
+                       fprintf(stderr,"Sendto ");
+                       goto out_err;
+               }
+       
+               server_addr_len = sizeof(server_addr);
+               while (recvfrom(sockfd, buf, sizeof(buf), 0,
+                           (struct sockaddr*)&server_addr,
+                           &server_addr_len) == -1){
+                       if (errno == EINTR) continue;
+                       fprintf(stderr,"Recvfrom ");
+                       goto out_err;           
+               }       
+       
+               printf("sent=%s received=%s", msg,buf);
+               if (!strcmp(msg,buf)) 
+                       printf(" -- OK\n");
+               else
+                       printf(" -- FAILED!!!\n");
+       }       
+
+       unlink(SOCKET_PATH_CLIENT);
+       close(sockfd);
+       return NULL;
+out_err:
+       unlink(SOCKET_PATH_CLIENT);
+       perror("- client");
+       close(sockfd);
+       return NULL;    
+}
+
+int main(int argc, char *argv[])
+{
+       char msg1[20]="Thread1";
+       /*char msg2[20]="Thread2";*/
+       pthread_attr_t attr;
+       pthread_t thread;
+               
+       pthread_attr_init(&attr);
+       pthread_create(&thread, &attr, messenger, (void*) msg1);
+       /*pthread_create(&thread, &attr, messenger, (void*) msg2);*/
+
+       while (1) { /* primitive wait but enough ;-) */
+               sleep(100000);
+       }
+}      
diff --git a/src/fwp/fwp/tests/unixsocktest/unixserver.c b/src/fwp/fwp/tests/unixsocktest/unixserver.c
new file mode 100644 (file)
index 0000000..69584fc
--- /dev/null
@@ -0,0 +1,78 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+int main()
+{
+       int server_sockfd, client_sockfd;
+       socklen_t client_len;
+       struct sockaddr_un server_addr;
+       struct sockaddr_un client_addr;
+       int mlen;
+
+       char buf[20];
+
+       /*  Remove any old socket and create 
+        *  an unnamed socket for the server.  */
+       
+       unlink("server_socket");
+       server_sockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+
+       /*  Name the socket.  */
+
+       server_addr.sun_family = AF_UNIX;
+       strcpy(server_addr.sun_path, "server_socket");
+       bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
+
+       /*  Create a connection queue and wait for clients.  */
+
+       listen(server_sockfd, 5);
+       while(1) {
+               client_sockfd = accept(server_sockfd, 
+                                      (struct sockaddr *)&client_addr, 
+                                      &client_len);
+/*             if (client_sockfd < 0) {
+                       if (errno==EINTR) continue;
+                       printf("Accept error \n");
+                       goto out_err;
+               }
+*/
+
+               switch (fork())
+               {
+               case 0:
+               close(server_sockfd);
+               while (1) {     
+                       while ((mlen = recv(client_sockfd, buf, sizeof(buf), 
+                                           0)) == -1){
+                               if (errno == EINTR) continue;
+                               goto out_err;           
+                       }       
+                       
+                       while (send(client_sockfd, buf, mlen, 0) == -1){
+                               if (errno == EINTR) continue;
+                               goto out_err;
+                       }
+               }
+      
+               case -1:
+                       return -1;
+               default:
+                       close(client_sockfd);
+               }       
+       }
+       
+       close(server_sockfd);
+       close(client_sockfd);
+       return 0;
+
+out_err:
+       perror("\n");
+       close(server_sockfd);
+       close(client_sockfd);
+       return -1;
+}
+
diff --git a/src/fwp/fwp/tests/unixsocktest/unixserver_dgram.c b/src/fwp/fwp/tests/unixsocktest/unixserver_dgram.c
new file mode 100644 (file)
index 0000000..d8136fd
--- /dev/null
@@ -0,0 +1,63 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define SOCKET_PATH_SERVER "server_socket"
+
+int main()
+{
+       int server_sockfd;
+       socklen_t addr_len;
+       struct sockaddr_un server_addr;
+       struct sockaddr_un client_addr;
+       int mlen;
+
+       char buf[100];
+
+       server_sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
+
+       unlink(SOCKET_PATH_SERVER);
+       server_addr.sun_family = AF_UNIX;
+       strcpy(server_addr.sun_path, SOCKET_PATH_SERVER);
+       
+       if (bind(server_sockfd, (struct sockaddr *)&server_addr, 
+                sizeof(server_addr)) < 0){
+               fprintf(stderr,"Bind ");
+               goto out_err;
+       }
+
+       
+       while (1) {     
+               addr_len = sizeof(client_addr); 
+               while ((mlen = recvfrom(server_sockfd, buf, sizeof(buf), 0, 
+                                       (struct sockaddr*)&client_addr,
+                                       &addr_len)) == -1){
+                       if (errno == EINTR) continue;
+                       fprintf(stderr,"Recvfrom  ");
+                       goto out_err;           
+               }       
+
+               printf("Prijate z %s\n",client_addr.sun_path);          
+               while (sendto(server_sockfd, buf, mlen, 0,
+                             (struct sockaddr*)&client_addr,
+                              addr_len) == -1){
+                       if (errno == EINTR) continue;   
+                       fprintf(stderr,"Sendto  ");
+                       goto out_err;
+               }
+       }
+      
+       close(server_sockfd);
+       unlink(SOCKET_PATH_SERVER);
+       return 0;
+
+out_err:
+       unlink(SOCKET_PATH_SERVER);
+       perror("-server error");
+       close(server_sockfd);
+       return -1;
+}
+
diff --git a/src/fwp/fwp/wme_test b/src/fwp/fwp/wme_test
new file mode 120000 (symlink)
index 0000000..236c4a2
--- /dev/null
@@ -0,0 +1 @@
+../wme_test
\ No newline at end of file
diff --git a/src/fwp/patches/ac_debug.patch b/src/fwp/patches/ac_debug.patch
new file mode 100644 (file)
index 0000000..9960313
--- /dev/null
@@ -0,0 +1,15 @@
+Index: linux2.6-devel/drivers/net/wireless/rt2x00/rt61pci.c
+===================================================================
+--- linux2.6-devel.orig/drivers/net/wireless/rt2x00/rt61pci.c  2007-11-26 19:40:10.000000000 +0100
++++ linux2.6-devel/drivers/net/wireless/rt2x00/rt61pci.c       2007-11-26 19:46:18.000000000 +0100
+@@ -1573,6 +1573,10 @@
+ {
+       u32 word;
++      printk(KERN_DEBUG "write_tx_desc: sent TX ring %d - CWmin: %d,"
++                      " CWmax: %d, AIFSN: %d.\n",
++                      desc->queue, desc->cw_min, desc->cw_max, desc->aifs);
++
+       /*
+        * Start writing the descriptor words.
+        */
diff --git a/src/fwp/patches/ac_param_setup_24-rc2.patch b/src/fwp/patches/ac_param_setup_24-rc2.patch
new file mode 100644 (file)
index 0000000..0d6d245
--- /dev/null
@@ -0,0 +1,67 @@
+Index: linux2.6-devel/drivers/net/wireless/rt2x00/rt2x00mac.c
+===================================================================
+--- linux2.6-devel.orig/drivers/net/wireless/rt2x00/rt2x00mac.c        2007-11-14 15:16:34.000000000 +0100
++++ linux2.6-devel/drivers/net/wireless/rt2x00/rt2x00mac.c     2007-11-14 17:09:44.000000000 +0100
+@@ -421,6 +421,7 @@
+        * The passed variables are stored as real value ((2^n)-1).
+        * Ralink registers require to know the bit number 'n'.
+        */
++#if 0
+       if (params->cw_min)
+               ring->tx_params.cw_min = fls(params->cw_min);
+       else
+@@ -435,6 +436,35 @@
+               ring->tx_params.aifs = params->aifs;
+       else
+               ring->tx_params.aifs = 2;
++#endif
++
++      switch (queue) {
++              case 0:
++                      ring->tx_params.aifs = 2;
++                      ring->tx_params.cw_max = 4;
++                      ring->tx_params.cw_min = 3;
++                      break;
++              case 1:
++                      ring->tx_params.aifs = 2;
++                      ring->tx_params.cw_max = 5;
++                      ring->tx_params.cw_min = 4;
++                      break;
++              case 2:
++                      ring->tx_params.aifs = 3;
++                      ring->tx_params.cw_max = 10;
++                      ring->tx_params.cw_min = 5;
++                      break;
++              case 3:
++                      ring->tx_params.aifs = 7;
++                      ring->tx_params.cw_max = 10;
++                      ring->tx_params.cw_min = 5;
++                      break;
++              default:
++                      ring->tx_params.aifs = 15;
++                      ring->tx_params.cw_max = 15;
++                      ring->tx_params.cw_min = 10;
++                      break;
++      }
+       INFO(rt2x00dev,
+            "Configured TX ring %d - CWmin: %d, CWmax: %d, Aifs: %d.\n",
+Index: linux2.6-devel/net/mac80211/wme.c
+===================================================================
+--- linux2.6-devel.orig/net/mac80211/wme.c     2007-11-14 15:16:34.000000000 +0100
++++ linux2.6-devel/net/mac80211/wme.c  2007-11-14 15:17:58.000000000 +0100
+@@ -112,12 +112,12 @@
+       /* is this a QoS frame? */
+       qos = fc & IEEE80211_STYPE_QOS_DATA;
+-
++#if 0
+       if (!qos) {
+               skb->priority = 0; /* required for correct WPA/11i MIC */
+               return ieee802_1d_to_ac[skb->priority];
+       }
+-
++#endif
+       /* use the data classifier to determine what 802.1d tag the
+        * data frame has */
+       skb->priority = classify_1d(skb, qd);
diff --git a/src/fwp/patches/ac_param_setup_24-rc3.patch b/src/fwp/patches/ac_param_setup_24-rc3.patch
new file mode 100644 (file)
index 0000000..e52bea8
--- /dev/null
@@ -0,0 +1,48 @@
+Index: linux2.6-devel/drivers/net/wireless/rt2x00/rt2x00mac.c
+===================================================================
+--- linux2.6-devel.orig/drivers/net/wireless/rt2x00/rt2x00mac.c        2007-12-04 10:47:32.000000000 +0100
++++ linux2.6-devel/drivers/net/wireless/rt2x00/rt2x00mac.c     2007-12-04 10:47:57.000000000 +0100
+@@ -421,6 +421,7 @@
+        * The passed variables are stored as real value ((2^n)-1).
+        * Ralink registers require to know the bit number 'n'.
+        */
++#if 0
+       if (params->cw_min)
+               ring->tx_params.cw_min = fls(params->cw_min);
+       else
+@@ -435,6 +436,35 @@
+               ring->tx_params.aifs = params->aifs;
+       else
+               ring->tx_params.aifs = 2;
++#endif
++
++      switch (queue) {
++              case 0:
++                      ring->tx_params.aifs = 2;
++                      ring->tx_params.cw_max = 4;
++                      ring->tx_params.cw_min = 3;
++                      break;
++              case 1:
++                      ring->tx_params.aifs = 2;
++                      ring->tx_params.cw_max = 5;
++                      ring->tx_params.cw_min = 4;
++                      break;
++              case 2:
++                      ring->tx_params.aifs = 3;
++                      ring->tx_params.cw_max = 10;
++                      ring->tx_params.cw_min = 5;
++                      break;
++              case 3:
++                      ring->tx_params.aifs = 7;
++                      ring->tx_params.cw_max = 10;
++                      ring->tx_params.cw_min = 5;
++                      break;
++              default:
++                      ring->tx_params.aifs = 7;
++                      ring->tx_params.cw_max = 10;
++                      ring->tx_params.cw_min = 5;
++                      break;
++      }
+       INFO(rt2x00dev,
+            "Configured TX ring %d - CWmin: %d, CWmax: %d, Aifs: %d.\n",
diff --git a/src/fwp/patches/qos_enable_24-rc3.patch b/src/fwp/patches/qos_enable_24-rc3.patch
new file mode 100644 (file)
index 0000000..cbc3547
--- /dev/null
@@ -0,0 +1,19 @@
+Index: linux2.6-devel/net/mac80211/wme.c
+===================================================================
+--- linux2.6-devel.orig/net/mac80211/wme.c     2007-12-04 10:59:30.000000000 +0100
++++ linux2.6-devel/net/mac80211/wme.c  2007-12-04 11:01:11.000000000 +0100
+@@ -112,12 +112,12 @@
+       /* is this a QoS frame? */
+       qos = fc & IEEE80211_STYPE_QOS_DATA;
+-
++#if 0
+       if (!qos) {
+               skb->priority = 0; /* required for correct WPA/11i MIC */
+               return ieee802_1d_to_ac[skb->priority];
+       }
+-
++#endif
+       /* use the data classifier to determine what 802.1d tag the
+        * data frame has */
+       skb->priority = classify_1d(skb, qd);
diff --git a/src/fwp/patches/series b/src/fwp/patches/series
new file mode 100644 (file)
index 0000000..8e0fb09
--- /dev/null
@@ -0,0 +1 @@
+ac_param_setup_24-rc3.patch
diff --git a/src/fwp/wme_test/.gitignore b/src/fwp/wme_test/.gitignore
new file mode 100644 (file)
index 0000000..52a54a0
--- /dev/null
@@ -0,0 +1,8 @@
+????-??-??_??:??:??
+*.dat
+*.pdf
+TAGS
+*~
+*.o
+wclient
+wserver
diff --git a/src/fwp/wme_test/Makefile b/src/fwp/wme_test/Makefile
new file mode 100644 (file)
index 0000000..f5892ac
--- /dev/null
@@ -0,0 +1,9 @@
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+include Makefile.std
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
diff --git a/src/fwp/wme_test/Makefile.omk b/src/fwp/wme_test/Makefile.omk
new file mode 100644 (file)
index 0000000..43ac0a5
--- /dev/null
@@ -0,0 +1,7 @@
+bin_PROGRAMS = fwptester fwptesterserver
+
+CFLAGS += -D_REENTRANT -g -DWITH_FWP
+lib_LOADLIBES = pthread  rt frsh ulut ncurses
+
+fwptester_SOURCES = wclient.c common.c
+fwptesterserver_SOURCES = wserver.c common.c
diff --git a/src/fwp/wme_test/Makefile.std b/src/fwp/wme_test/Makefile.std
new file mode 100644 (file)
index 0000000..58b3f72
--- /dev/null
@@ -0,0 +1,20 @@
+# Non-OMK Makefile
+
+PROGS = wserver wclient schedlat
+
+all: $(PROGS) 
+.PHONY:all
+
+LDFLAGS = -lpthread  -lrt -lncurses
+CFLAGS += -Wall -D_REENTRANT -g -O2
+ifdef DEBUG
+CFLAGS += -DDEBUG=1
+endif
+
+wserver: wserver.o common.o
+wclient: wclient.o common.o
+schedlat: schedlat.o common.o
+
+clean:
+       rm -rf ./*.o
+       rm -f $(PROGS)
diff --git a/src/fwp/wme_test/be_influence2/graph2 b/src/fwp/wme_test/be_influence2/graph2
new file mode 100755 (executable)
index 0000000..78f3931
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+for i in BE BK; do
+    ./plot2 -d 150 -P -o ${i}_influence_queue_comp.pdf `cat prefixes_$i`
+done
diff --git a/src/fwp/wme_test/be_influence2/plot2 b/src/fwp/wme_test/be_influence2/plot2
new file mode 100755 (executable)
index 0000000..33dfb8e
--- /dev/null
@@ -0,0 +1,101 @@
+#!/bin/sh
+
+SET_TERM_TEMPLATE='set term push; set term x11 enhanced; set term wxt enhanced; set term pop'
+
+DELAY_BOUND="[]"
+
+while getopts d:enso:pP opt
+do
+    case $opt in
+       d) DELAY_BOUND="[0:$OPTARG]";;
+       e) SET_TERM_TEMPLATE='set term postscript color eps enhanced; set output "${FILE}.eps"';;
+       n) SET_TERM_TEMPLATE='set term png enhanced; set output "${FILE}.png"';;
+       s) SET_TERM_TEMPLATE='set term svg enhanced; set output "${FILE}.svg"';;
+       o) MULTIPDF_FILENAME=$OPTARG;;
+       p)
+           SET_TERM_TEMPLATE='set term postscript color landscape enhanced'
+           PDF_OUTPUT=1
+           ;;
+       P)
+           SET_TERM_TEMPLATE='set term postscript color portrait enhanced'
+           MULTIPLE_GRAPHS_IN_PDF=1
+           GNUPLOT_CMD_FILE=plot_commands.$$
+           rm -f ${GNUPLOT_CMD_FILE}
+           ;;
+    esac
+done
+
+shift $(($OPTIND - 1))
+
+[ $# -eq 0 -a -r delay_stats.dat ] && set delay_stats.dat
+
+for i in `seq 0 20 340`; do
+    FILE1=`printf $1_%03d $i`
+    FILE2=`printf $2_%03d $i`
+    FILE3=`printf $3_%03d $i`
+#     FILE1=`printf 2008-01-22_10:41:16_%03d $i`
+#     FILE2=`printf 2008-01-22_11:28:12_%03d $i`
+#     FILE3=`printf 2008-01-22_13:40:17_%03d $i`
+
+    COMMAND1="Results of: $(grep 'Invoked as' ${FILE1}.dat|grep -o 'wclient.*'|sed -e 's/ -o [^ ]*//' -e 's/ [^ ]* ?$//')"
+    COMMAND2="Results of: $(grep 'Invoked as' ${FILE2}.dat|grep -o 'wclient.*'|sed -e 's/ -o [^ ]*//' -e 's/ [^ ]* ?$//')"
+    COMMAND3="Results of: $(grep 'Invoked as' ${FILE3}.dat|grep -o 'wclient.*'|sed -e 's/ -o [^ ]*//' -e 's/ [^ ]* ?$//')"
+    STREAMS1="$(grep '^#' ${FILE1}.dat|sed -ne '2,$ s/^# //p'|while read LINE; do echo $LINE\\n; done|tr -d '\n')"
+    STREAMS2="$(grep '^#' ${FILE2}.dat|sed -ne '2,$ s/^# //p'|while read LINE; do echo $LINE\\n; done|tr -d '\n')"
+    STREAMS3="$(grep '^#' ${FILE3}.dat|sed -ne '2,$ s/^# //p'|while read LINE; do echo $LINE\\n; done|tr -d '\n')"
+
+    SET_TERM=$(echo $SET_TERM_TEMPLATE|sed -e s/\${FILE1}/$FILE1/)
+    if [ -n "$MULTIPLE_GRAPHS_IN_PDF" ]; then
+       CMD="cat >>$GNUPLOT_CMD_FILE"
+    elif [ -n "$PDF_OUTPUT" ]; then
+       CMD="cat | gnuplot | ps2pdf - ${FILE}.pdf"
+    else 
+       CMD="cat | gnuplot -persist"
+    fi
+    eval $CMD <<EOF
+${SET_TERM}
+unset label
+set xlabel "Response-Time [ms]"
+set ylabel "Cumulative % of packets"
+set key right bottom nobox
+set style data lines
+set style line 1 lw 5 lt 1 lc rgb "red"
+set style line 2 lw 5 lt 1 lc rgb "green"
+set style line 3 lw 5 lt 1 lc rgb "blue"
+set style line 4 lw 5 lt 1 lc rgb "magenta"
+set ytics 10
+set size 1,0.8
+set grid
+set multiplot layout 3,1
+set title "${COMMAND1}" noenhanced offset 0,1.5
+unset label
+set label "${STREAMS1}" noenhanced at graph 0,1.22 font "Helvetica,7"
+plot $DELAY_BOUND  [0.01:100]\
+     "${FILE1}.dat" index 0 with lines ls 1 title "AC\\\\_VO",\
+     "${FILE1}.dat" index 1 with lines ls 2 title "AC\\\\_VI",\
+     "${FILE1}.dat" index 2 with lines ls 3 title "AC\\\\_BE",\
+     "${FILE1}.dat" index 3 with lines ls 4 title "AC\\\\_BK"
+set title "${COMMAND2}" noenhanced
+unset label
+set label "${STREAMS2}" noenhanced at graph 0,1.22 font "Helvetica,7"
+plot $DELAY_BOUND [0.01:100]\
+     "${FILE2}.dat" index 0 with lines ls 1 title "AC\\\\_VO with queue",\
+     "${FILE2}.dat" index 1 with lines ls 2 title "AC\\\\_VI with queue",\
+     "${FILE2}.dat" index 2 with lines ls 3 title "AC\\\\_BE with queue",\
+     "${FILE2}.dat" index 3 with lines ls 4 title "AC\\\\_BK with queue"
+set title "${COMMAND3}" noenhanced
+unset label
+set label "${STREAMS3}" noenhanced at graph 0,1.22 font "Helvetica,7"
+plot $DELAY_BOUND [0.01:100]\
+     "${FILE3}.dat" index 0 with lines ls 1 title "AC\\\\_VO with bigger queue",\
+     "${FILE3}.dat" index 1 with lines ls 2 title "AC\\\\_VI with bigger queue",\
+     "${FILE3}.dat" index 2 with lines ls 3 title "AC\\\\_BE with bigger queue",\
+     "${FILE3}.dat" index 3 with lines ls 4 title "AC\\\\_BK with bigger queue"
+unset multiplot
+EOF
+done
+
+if [ -n "$MULTIPLE_GRAPHS_IN_PDF" ]; then
+    gnuplot $GNUPLOT_CMD_FILE|ps2pdf - $MULTIPDF_FILENAME
+    rm -f $GNUPLOT_CMD_FILE
+fi
diff --git a/src/fwp/wme_test/be_influence2/run b/src/fwp/wme_test/be_influence2/run
new file mode 100755 (executable)
index 0000000..e0da765
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+PREFIX=$(date +%F_%T)
+
+for i in `seq 0 20 340`; do
+    ../wclient -Q 10000 -q -B 100 -b VO,VI,BE:$i -j 50 -s 800 -c 60 -o `printf ${PREFIX}_%03d $i` 192.168.1.100
+done
+
+../plot -d 150 -P -o be_influence_${PREFIX}.pdf ${PREFIX}_*.dat
diff --git a/src/fwp/wme_test/be_influence2/run2 b/src/fwp/wme_test/be_influence2/run2
new file mode 100755 (executable)
index 0000000..a6f5a53
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+for queue in BE BK; do
+    for Qsize in 0 3000 6000; do
+       PREFIX=$(date +%F_%T)_${queue}
+       echo $PREFIX >> prefixes_$queue
+       for i in `seq 0 20 340`; do
+           ../wclient -Q $Qsize -q -B 100 -b VO,VI,$queue:$i -j 50 -s 800 -c 60 -o `printf ${PREFIX}_%03d $i` 192.168.1.100
+       done
+    
+       ../plot -d 150 -P -o be_influence_${PREFIX}.pdf ${PREFIX}_*.dat
+    done
+done
diff --git a/src/fwp/wme_test/common.c b/src/fwp/wme_test/common.c
new file mode 100644 (file)
index 0000000..1bbe433
--- /dev/null
@@ -0,0 +1,100 @@
+#include "common.h"
+#include <sched.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <error.h>
+#include <errno.h>
+
+const int prio_to_ac[8] = {2,3,3,2,1,1,0,0};
+const unsigned int ac_to_tos[4] = {224,160,96,64};
+const char *ac_to_text[4] = {[AC_VO] = "AC_VO", [AC_VI] = "AC_VI", [AC_BE] = "AC_BE", [AC_BK] = "AC_BK", };
+
+void set_rt_prio(int priority)
+{
+       int maxpri, minpri;
+       static struct sched_param param;
+
+       if ((maxpri = sched_get_priority_max(SCHED_FIFO)) == -1)        {
+               error(8, errno, "sched_get_priority_max fails");
+       }
+
+       if ((minpri = sched_get_priority_min(SCHED_FIFO)) == -1)        {
+               error(10, errno, "sched_get_priority_min fails");
+       }
+
+       if (priority > maxpri)  {
+               error(9, 0, "maximum priority allowed is %d.\n", maxpri);
+       }
+       if (priority < minpri)  {
+               error(11, 0, "minimum priority allowed is %d.\n", minpri);
+       }
+
+       param.sched_priority = priority;
+
+       if (sched_setscheduler(0, SCHED_FIFO, &param) == -1)    {
+               error(0, errno, "sched_setscheduler fails");
+#ifndef WITH_FWP
+               exit(13);
+#endif
+       }
+}
+
+void block_signals(void)
+{
+       sigset_t sigset;
+       int ret;
+       sigemptyset(&sigset);
+       sigaddset(&sigset, SIGINT);
+       sigaddset(&sigset, SIGTERM);
+       ret = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+       if (ret != 0) {
+               perror("pthread_sigmask failed");
+               exit(1);
+       }
+}
+
+static char *num_with_unit(char *buf, unsigned num, const char *units[])
+{
+       const int div[] = {100,10,1};
+       unsigned order = 0;
+       int d;
+
+       while (num > 999 && units[(order+3)/3] != NULL) {
+               num /= 10;
+               order++;
+       }
+
+       d = div[(order+2)%3];
+       if (d == 1)
+               sprintf(buf, "%4d %s", num, units[(order+2)/3]);
+       else
+               sprintf(buf, "%d.%.*d %s", num/d, (d==10) ? 1 : 2, num%d, units[(order+2)/3]);
+       return buf;
+}
+
+char *bandwidth_to_text(char *buf, unsigned bandwidth_bps)
+{
+       const char *unit[] = {"bps", "kbps", "Mbps", NULL};
+       return num_with_unit(buf, bandwidth_bps, unit);
+}
+
+char *usec_to_text(char *buf, unsigned usec)
+{
+       const char *unit[] = {"us", "ms", "s", NULL};
+       return num_with_unit(buf, usec, unit);
+}
+
+
+static void test_usec_to_text() __attribute__((unused));
+static void test_usec_to_text()
+{
+       int num=0;
+       char buf[1000];
+       int i;
+       for (i=1; i<11; i++) {
+               num = num*10 + i;
+               printf("%s = %d\n", usec_to_text(buf, num), num);
+       }
+}
+       
diff --git a/src/fwp/wme_test/common.h b/src/fwp/wme_test/common.h
new file mode 100644 (file)
index 0000000..17ae3fc
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <time.h>
+#include <stdint.h>
+
+#define BASE_PORT      5100
+#define AC_NUM         4
+#define MTU            800 
+#define        BUFFSIZE        65536
+
+#define Kbit 1000
+#define Mbit (Kbit*Kbit)
+
+#define SEC_TO_USEC       1000000LL
+#define MSEC_TO_USEC      1000LL
+#define USEC_TO_NSEC      1000LL
+
+enum ac {
+       AC_VO = 0,
+       AC_VI = 1,
+       AC_BE = 2,
+       AC_BK = 3
+};
+
+struct msg_t {
+/*     unsigned int tos; */
+       uint64_t send_timestamp; /* [nsec] */
+       uint64_t sendback_timestamp; /* [nsec] */
+/*     unsigned long int seqn; */
+       uint32_t stream;
+#ifdef WITH_FWP
+       uint16_t resp_port;
+#endif
+} __attribute__((packed));
+
+union msg_buff {
+       struct msg_t msg;
+       char nonsense[BUFFSIZE];
+};
+
+
+extern const int prio_to_ac[8];
+extern const unsigned int ac_to_tos[4];
+extern const char *ac_to_text[4];
+
+void block_signals(void);
+void set_rt_prio(int priority);
+char *bandwidth_to_text(char *buf, unsigned bandwidth_bps);
+char *usec_to_text(char *buf, unsigned usec);
+
+static inline 
+void timespec_add (struct timespec *sum, const struct timespec *left,
+             const struct timespec *right)
+{
+       sum->tv_sec = left->tv_sec + right->tv_sec;
+       sum->tv_nsec = left->tv_nsec + right->tv_nsec;
+
+       if (sum->tv_nsec >= 1000000000){
+               ++sum->tv_sec;
+               sum->tv_nsec -= 1000000000;
+       }
+}
+
+static inline 
+void timespec_sub (struct timespec *diff, const struct timespec *left,
+             const struct timespec *right)
+{
+       diff->tv_sec = left->tv_sec - right->tv_sec;
+       diff->tv_nsec = left->tv_nsec - right->tv_nsec;
+
+       if (diff->tv_nsec < 0){
+                 --diff->tv_sec;
+                 diff->tv_nsec += 1000000000;
+       }
+}
+
+static inline long long timespec_sub_usec(const struct timespec *left,
+                                         const struct timespec *right)
+{
+       struct timespec result;
+       timespec_sub(&result, left, right);
+       return (long long)result.tv_sec * SEC_TO_USEC +
+               result.tv_nsec / USEC_TO_NSEC;
+}
+
+static inline long long timespec2usec(const struct timespec *ts)
+{
+       return ts->tv_sec * SEC_TO_USEC + ts->tv_nsec / USEC_TO_NSEC;
+}
+
+#endif
diff --git a/src/fwp/wme_test/more_sta/plot b/src/fwp/wme_test/more_sta/plot
new file mode 100755 (executable)
index 0000000..e2fc2ef
--- /dev/null
@@ -0,0 +1,31 @@
+#!/usr/bin/perl -w
+use Getopt::Std;
+
+my %opt;
+getopts('d:', \%opt);
+
+$DELAY_BOUND="[]";
+$DELAY_BOUND="[0:".$opt{'d'}."]" if $opt{'d'};
+
+foreach $prefix (split(' ', `ls *.dat|grep -o '^[0-9]\\+-..'|sort -u`)) {
+    print "$prefix\n";
+    open CMD, "| gnuplot | ps2pdf - ${prefix}.pdf";
+    print CMD qq/
+set term postscript color landscape
+set xlabel "Response-Time [ms]"
+set ylabel "Cumulative % of packets"
+set key right bottom nobox
+set style data linespoints
+#set logscale x
+set grid
+# set size 1,0.8
+# unset label
+# set label "\${COMMAND}" noenhanced at graph 0,1.3
+# set label "\${STREAMS}" noenhanced at graph 0,1.2 font "Helvetica,9"
+/;
+    print CMD "plot $DELAY_BOUND [0.01:100] ";
+    @files=glob "${prefix}*.dat";
+    @plots=map qq/"$_" using 1:2/, @files;
+    print CMD join ',', @plots;
+    close CMD;
+}
diff --git a/src/fwp/wme_test/more_sta/plot-wlans b/src/fwp/wme_test/more_sta/plot-wlans
new file mode 100755 (executable)
index 0000000..c84c0fc
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+EXPERIMENTS=`ls -1 *.dat|egrep -o '^[0-9]+-..'|sort -u`
+
+
+for e in $EXPERIMENTS; do
+    echo "Plotting $e..."
+    ../plot -P -m -t "1 STA;2 STAs;3 STAs;4 STAs" -o $e.pdf $e-?-stas.dat
+done
diff --git a/src/fwp/wme_test/more_sta/run b/src/fwp/wme_test/more_sta/run
new file mode 100755 (executable)
index 0000000..c52922f
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+export RUNAT="192.168.1.103 localhost/wlan0 localhost/wlan1"
+dest=192.168.1.2
+
+num_sta=$(echo $RUNAT|wc -w)
+
+for tbw in `seq 210 -10 100`; do
+    bw=$((tbw/$num_sta))
+    for ac in VO VI BE BK; do
+       params="-B $bw -b $ac -j 50 -s 100 -q -c 15"
+       for i in $(seq $num_sta); do
+           wclient -I wlan1 $params -o $tbw-$ac-onesta-wlan1-$i $dest &
+       done
+       wait
+       sleep 1
+
+       for i in $(seq $num_sta); do
+           wclient -I wlan0 $params -o $tbw-$ac-onesta-wlan0-$i $dest &
+       done
+       wait
+       sleep 1
+
+       echo "____________________"
+       ./wclientpar $params -o $tbw-$ac-paralel $dest
+       sleep 1
+       echo "===================="
+    done
+done
diff --git a/src/fwp/wme_test/more_sta/run-wlans b/src/fwp/wme_test/more_sta/run-wlans
new file mode 100755 (executable)
index 0000000..d3b2147
--- /dev/null
@@ -0,0 +1,42 @@
+#!/usr/bin/perl -w
+@run_at = qw|localhost/wlan0 localhost/wlan1 localhost/wlan2 localhost/wlan3|;
+$dest = "192.168.1.2";
+
+sub run {
+    my $at = shift; 
+    my @args = @_;
+
+    my ($host, $iface) = split(/\//, $run_at[$at], 2);
+    unshift @args, ('-I', $iface) if (defined $iface);
+    unshift @args, ('wclient');
+    unshift @args, ('ssh', $host) if ($host ne 'localhost');
+    print "running ", join(' ', @args), "\n";
+    if (fork() == 0) {
+       exec(@args);
+       exit();
+    }
+}
+
+
+for ($tbw=10; $tbw<=30; $tbw+=5) {
+    foreach $ac(qw/VO VI BE BK/) {
+       for ($i=1; $i <= @run_at; $i++) {
+           $at = 0;
+
+           @args = (split(/ +/,"-B $tbw -b $ac -j 50 -s 100 -c 60  $dest"), ("-C", "$i STAs"));
+           run($at, (@args, ('-o', "$tbw-$ac-$i-stas")));
+           # Run first tasks at [0] and the remaining in 
+           for ($j=1; $j<@run_at; $j++) {
+               if ($j > @run_at - $i) { $at++; }
+               run($at, (@args, ('-o', "$tbw-$ac-$i-stas-$j")));
+           }
+           print "==================\n";
+           
+           for ($j=1; $j <= @run_at; $j++) {
+               wait();
+           }
+           sleep(1);
+       }
+    }
+}
+
diff --git a/src/fwp/wme_test/more_sta/wclientpar b/src/fwp/wme_test/more_sta/wclientpar
new file mode 100755 (executable)
index 0000000..b4f9ac6
--- /dev/null
@@ -0,0 +1,44 @@
+#!/usr/bin/perl -w
+
+# Runs wclient with given parameters on the host (and interface) given
+# by RUNAT environment variable.
+
+sub get_output {
+    my @a=@ARGV;
+    my $output = "delay_stats";
+    while ($#a >= 0) {
+       if ($a[0] eq "-o") {
+           $output = $a[1];
+       };
+       shift @a;
+    }
+    return $output;
+}
+
+@run_at = qw!localhost localhost localhost/wlan1!;
+@run_at = split(/ +/, $ENV{'RUNAT'}) if $ENV{'RUNAT'};
+
+$i = 0;
+my %outputs;
+foreach $run (@run_at) {
+    ($host, $iface) = split(/\//, $run, 2);
+    @args = ();
+    push @args, ('ssh', $host) if ($host ne 'localhost');
+    push @args, ('wclient');
+    push @args, ('-I', $iface) if (defined $iface);
+    push @args, @ARGV;
+    $output = get_output();
+    $output .= sprintf("-%s%s", $host, defined $iface ? "-$iface":"");
+    if ($outputs{$output}) { $output .= sprintf("-%02d", $i); }
+    $outputs{$output} = 1;
+    push(@args, ('-o', $output));
+    if (fork() == 0) {
+       print "running ", join(' ', @args), "\n";
+       exec(@args);
+       exit();
+    }
+    $i++;
+}
+foreach $run (@run_at) {
+    wait();
+}
diff --git a/src/fwp/wme_test/plot b/src/fwp/wme_test/plot
new file mode 100755 (executable)
index 0000000..871283a
--- /dev/null
@@ -0,0 +1,166 @@
+#!/usr/bin/perl -w
+use Getopt::Std;
+use File::Basename;
+
+# Default values
+$SET_TERM_TEMPLATE='set term push; set term x11 enhanced; set term wxt enhanced; set term pop';
+$DELAY_BOUND="[]";
+$MULTIPDF_FILENAME="all.pdf";
+
+# Process command line options
+my %opt;
+getopts('bd:emnso:pPt:', \%opt);
+$PLOT_SINGLE_EXPERIMENT = $opt{'m'} ? 0 : 1;
+$EXPERIMENT_TITLES = $opt{'t'};
+$PLOT_BOTH_DIRECTIONS=1 if $opt{'b'};
+$DELAY_BOUND="[0:".$opt{'d'}."]" if $opt{'d'};
+$SET_TERM_TEMPLATE='set term postscript color eps enhanced; set output "${FILE}.eps"' if $opt{'e'};
+$SET_TERM_TEMPLATE='set term png enhanced; set output "${FILE}.png"' if $opt{'n'};
+$SET_TERM_TEMPLATE='set term svg enhanced; set output "${FILE}.svg"' if $opt{'s'};
+$MULTIPDF_FILENAME=$opt{'o'} if $opt{'o'};
+if ($opt{'p'}) {
+    $SET_TERM_TEMPLATE='set term postscript color landscape enhanced';
+    $PDF_OUTPUT=1;
+}
+if ($opt{'P'}) {
+    $SET_TERM_TEMPLATE='set term postscript color landscape enhanced';
+    $MULTIPLE_GRAPHS_IN_PDF=1;
+    $GNUPLOT_CMD_FILE="plot_commands.$$";
+    unlink ${GNUPLOT_CMD_FILE};
+}
+
+if ($#ARGV < 0 && -r "delay_stats.dat") {$ARGV[0]="delay_stats.dat";}
+
+# Process the data files and plot graph(s)
+foreach $dat_file (@ARGV) {
+    ($FILE, , ) = fileparse($dat_file, (".dat"));
+
+    # Get labels from data file
+    $COMMAND="";
+    $STREAMS="";
+    open F, $dat_file;
+    while (<F>) {
+       if (/wclient.*/) {
+           $_=$&;
+           s/ -o [^ ]*//g;
+           $COMMAND="Results of: $_";
+           #$COMMAND="Results of: grep -o 'wclient.*'|sed -e 's/ -o [^ ]*//' -e 's/ [^ ]* ?$//')"
+       } elsif (/^#[^#] */) {
+           $STREAMS .= "$'";
+       }
+       
+       
+    }
+    close F;
+    $STREAMS =~ s/\n/\\n/g;
+
+    if ($MULTIPLE_GRAPHS_IN_PDF) {
+       open CMD, ">>$GNUPLOT_CMD_FILE";
+    } elsif ($PDF_OUTPUT) {
+       open CMD, "| gnuplot | ps2pdf - ${FILE}.pdf";
+    } else {
+       open CMD, "| gnuplot -persist";
+    }
+#     close CMD;
+#     open CMD, ">&STDOUT";
+    $SET_TERM = $SET_TERM_TEMPLATE;
+    $SET_TERM =~ s/\${FILE}/$FILE/;
+
+    print CMD qq/
+${SET_TERM}
+set xlabel "Response-Time [ms]"
+set ylabel "Cumulative % of packets"
+set key right bottom nobox
+set style data linespoints
+#set logscale x
+set grid
+set size 1,0.8
+unset label
+set label "${COMMAND}" noenhanced at graph 0,1.3
+set label "${STREAMS}" noenhanced at graph 0,1.2 font "Helvetica,9"
+/;
+    if ($PLOT_SINGLE_EXPERIMENT) {
+       print CMD qq/
+set style line 1  lt 1 lc rgb "red"
+set style line 2  lt 1 lc rgb "green"
+set style line 3  lt 1 lc rgb "blue"
+set style line 4  lt 1 lc rgb "magenta"
+set style line 5  lt 2 lc rgb "red" lw 2
+set style line 6  lt 2 lc rgb "green" lw 2
+set style line 7  lt 2 lc rgb "blue" lw 2
+set style line 8  lt 2 lc rgb "magenta" lw 2
+set style line 9  lt 3 lc rgb "red" lw 2
+set style line 10 lt 3 lc rgb "green" lw 2
+set style line 11 lt 3 lc rgb "blue" lw 2
+set style line 12 lt 3 lc rgb "magenta" lw 2
+/;
+       print CMD qq/plot $DELAY_BOUND [0.01:100]\\
+     "${FILE}.dat" index 0 using 1:2 with linespoints ls 1 title "AC\\\\_VO",\\
+     "${FILE}.dat" index 1 using 1:2 with linespoints ls 2 title "AC\\\\_VI",\\
+     "${FILE}.dat" index 2 using 1:2 with linespoints ls 3 title "AC\\\\_BE",\\
+     "${FILE}.dat" index 3 using 1:2 with linespoints ls 4 title "AC\\\\_BK"/;
+
+       if ($PLOT_BOTH_DIRECTIONS) {
+           print CMD qq/,\\
+     "${FILE}.dat" index 0 using 1:3 with lines ls 5  title "AC\\\\_VO cs",\\
+     "${FILE}.dat" index 1 using 1:3 with lines ls 6  title "AC\\\\_VI cs",\\
+     "${FILE}.dat" index 2 using 1:3 with lines ls 7  title "AC\\\\_BE cs",\\
+     "${FILE}.dat" index 3 using 1:3 with lines ls 8  title "AC\\\\_BK cs",\\
+     "${FILE}.dat" index 0 using 1:4 with lines ls 9  title "AC\\\\_VO sc",\\
+     "${FILE}.dat" index 1 using 1:4 with lines ls 10 title "AC\\\\_VI sc",\\
+     "${FILE}.dat" index 2 using 1:4 with lines ls 11 title "AC\\\\_BE sc",\\
+     "${FILE}.dat" index 3 using 1:4 with lines ls 12 title "AC\\\\_BK sc"
+/;
+       } else {
+           print CMD "\n";
+       }
+    } else {
+       # Multiple experiments in a single plot
+       print CMD qq/
+set style line 1  lt 1 lc rgb "red" lw 2
+set style line 2  lt 1 lc rgb "green" lw 2
+set style line 3  lt 1 lc rgb "blue" lw 2
+set style line 4  lt 1 lc rgb "magenta" lw 2
+set style line 5  lt 2 lc rgb "red" lw 2
+set style line 6  lt 2 lc rgb "green" lw 2
+set style line 7  lt 2 lc rgb "blue" lw 2
+set style line 8  lt 2 lc rgb "magenta" lw 2
+set style line 9  lt 3 lc rgb "red" lw 2
+set style line 10 lt 3 lc rgb "green" lw 2
+set style line 11 lt 3 lc rgb "blue" lw 2
+set style line 12 lt 3 lc rgb "magenta" lw 2
+/;
+       my ($ls1, $ls2, $ls3, $ls4) = (1,2,3,4);
+       my @titles = split(/;/, $EXPERIMENT_TITLES);
+       my $experiment = 0;
+       my $t=$titles[$experiment];
+       $t = '' unless $t;
+       print CMD qq/plot $DELAY_BOUND [0.01:100]\\
+     "${FILE}.dat" index 0 using 1:2 with lines ls $ls1 title "AC\\\\_VO $t",\\
+     "${FILE}.dat" index 1 using 1:2 with lines ls $ls2 title "AC\\\\_VI $t",\\
+     "${FILE}.dat" index 2 using 1:2 with lines ls $ls3 title "AC\\\\_BE $t",\\
+     "${FILE}.dat" index 3 using 1:2 with lines ls $ls4 title "AC\\\\_BK $t"/;
+       foreach $dat_file (@ARGV[1,2]) {
+           last if (!defined $dat_file);
+           $experiment++;
+           $t=$titles[$experiment];
+           $t = '' unless $t;
+           ($FILE, , ) = fileparse($dat_file, (".dat"));
+           ($ls1, $ls2, $ls3, $ls4) = map($_+4, ($ls1, $ls2, $ls3, $ls4));
+           print CMD qq/,\\
+     "${FILE}.dat" index 0 using 1:2 with lines ls $ls1 title "AC\\\\_VO $t",\\
+     "${FILE}.dat" index 1 using 1:2 with lines ls $ls2 title "AC\\\\_VI $t",\\
+     "${FILE}.dat" index 2 using 1:2 with lines ls $ls3 title "AC\\\\_BE $t",\\
+     "${FILE}.dat" index 3 using 1:2 with lines ls $ls4 title "AC\\\\_BK $t"/;
+       }
+       print CMD "\n";
+       last;
+    }
+
+    close CMD;
+}
+
+if ($MULTIPLE_GRAPHS_IN_PDF) {
+    system("gnuplot $GNUPLOT_CMD_FILE|ps2pdf - $MULTIPDF_FILENAME");
+    unlink ${GNUPLOT_CMD_FILE};
+}
diff --git a/src/fwp/wme_test/plot_commands b/src/fwp/wme_test/plot_commands
new file mode 100644 (file)
index 0000000..af88c8a
--- /dev/null
@@ -0,0 +1,15 @@
+set term postscript color
+set output 'delay_stats.eps'
+#set term x11
+#set title "TITLE"
+set xlabel "Delay (ms)"
+set ylabel "Packet percentage"
+set key right top nobox
+set grid
+plot [0:*] [0.01:*] "delay_stats.dat" using 1:2 smooth csplines title "AC_VO",\
+                   "delay_stats.dat" using 1:3 smooth csplines title "AC_VI",\
+                   "delay_stats.dat" using 1:4 smooth csplines title "AC_BE",\
+                   "delay_stats.dat" using 1:5 smooth csplines title "AC_BK"
+#set term postscript color eps size 12cm,9cm
+#set output '${FILE}.eps'
+#replot
diff --git a/src/fwp/wme_test/run b/src/fwp/wme_test/run
new file mode 100755 (executable)
index 0000000..f205379
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+set -e
+
+FILE=delay_stats
+
+ARGV="$@"
+
+while [ $# -gt 0 ]
+do
+    case $1 in
+        -o)    FILE="$2";;
+    esac
+    shift
+done
+
+`dirname $0`/wclient $ARGV
+
+`dirname $0`/plot $FILE.dat
diff --git a/src/fwp/wme_test/sat_per_packet_size/graph b/src/fwp/wme_test/sat_per_packet_size/graph
new file mode 100755 (executable)
index 0000000..84f1a36
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+for q in BE VI VO; do
+    ../plot -d 300 -o ${q}_packet_size_300.pdf -P ${q}_packet_size_*.dat
+#    ../plot -d 2000 -o ${q}_packet_size_2000.pdf -P ${q}_packet_size_*.dat
+done
+./sat-graph
+./sat-graph -m    
+
+
+
diff --git a/src/fwp/wme_test/sat_per_packet_size/run b/src/fwp/wme_test/sat_per_packet_size/run
new file mode 100755 (executable)
index 0000000..0682bbb
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+for i in 12 `seq 20 10 200` `seq 250 50 1400` `seq 1450 10 1520` `seq 1550 50 2000`
+do
+       ../wclient -q -Q 3000 -B 100 -b VO/$i,VI,BE:500 -j 50 -s 800 -c 50 -o `printf VO_packet_size_%04d $i` 192.168.1.100
+       ../wclient -q -Q 3000 -B 100 -b VO,VI/$i,BE:500 -j 50 -s 800 -c 50 -o `printf VI_packet_size_%04d $i` 192.168.1.100
+       ../wclient -q -Q 3000 -B 100 -b VO,VI,BE:500/$i -j 50 -s 800 -c 50 -o `printf BE_packet_size_%04d $i` 192.168.1.100
+done
diff --git a/src/fwp/wme_test/sat_per_packet_size/sat-graph b/src/fwp/wme_test/sat_per_packet_size/sat-graph
new file mode 100755 (executable)
index 0000000..d1bd5a5
--- /dev/null
@@ -0,0 +1,81 @@
+#!/usr/bin/perl -w
+
+$pdf_output=1;
+$multiple_graphs=1 if ($#ARGV >= 0 && $ARGV[0] eq "-m");
+
+#$Q=$ARGV[0] || "VI";
+
+foreach $Q (("VO", "VI", "BE")) {
+    
+    $base_name="${Q}_packet_size_";
+    $graph_data_name = "${base_name}graph";
+
+    open G, ">$graph_data_name" || die "error opening $graph_data_name";
+    foreach $f (glob "${base_name}*.dat") {
+       open F, $f;
+       while (<F>) {
+           if (/AC_${Q}/) {
+               ($a) = /([0-9]*) bytes/;
+               ($b)=/real: +([0-9.]+) kbps/;
+           }
+           if (/AC_BE/) {
+               ($c) = /real: +([0-9.]+) kbps/;
+               if (!$c) {
+                   ($c) = /real: +([0-9.]+) bps/;
+                   $c/=1000.0;
+               }
+               print G "$a $b $c\n";
+           }
+       }
+       close F;    
+    }
+    close G;
+}
+if ($pdf_output) {
+    if ($multiple_graphs) {
+       $pdf = "packet_sizes_sat.pdf";
+    } else {
+       $pdf = "packet_sizes_sat_comp.pdf";
+    }
+    open GNUPLOT, "|gnuplot|ps2pdf - $pdf";
+    print GNUPLOT "set term postscript color landscape\n";
+} else {
+    open GNUPLOT, "|gnuplot -persist";
+}
+
+print GNUPLOT <<EOF;
+#set key off
+set key right bottom nobox
+set style data linespoints
+set grid
+EOF
+
+if ($multiple_graphs) {
+    foreach $Q (("VO", "VI", "BE")) {
+       $base_name="${Q}_packet_size_";
+       $graph_data_name = "${base_name}graph";
+       
+       print GNUPLOT qq/set title "Influence of AC_$Q packet sizes to saturation bandwidth of AC_BE"\n/;
+       print GNUPLOT qq/set xlabel "AC_$Q packet sizes [bytes]"\n/;
+       print GNUPLOT qq/set ylabel "Bandwidth [kbps]"\n/;
+       print GNUPLOT qq/plot /;
+       if ($Q ne "BE") {
+           print GNUPLOT qq/"$graph_data_name" using 1:3 title "AC_BE", /;
+       }
+       print GNUPLOT qq/"$graph_data_name" using 1:2 title "AC_${Q}"\n/;
+    }
+} else {
+    print GNUPLOT qq/set title "Influence of different packet sizes to saturation bandwidth of AC_BE"\n/;
+    print GNUPLOT qq/set xlabel "Packet sizes [bytes]"\n/;
+    print GNUPLOT qq/set ylabel "AC_BE bandwidth [kbps]"\n/;
+    @plots=();
+    foreach $Q (("VO", "VI", "BE")) {
+       $base_name="${Q}_packet_size_";
+       $graph_data_name = "${base_name}graph";
+       
+       push @plots, qq/"$graph_data_name" using 1:3 title "packet size of AC_${Q} was being changed"/;
+    }
+    print GNUPLOT "plot ", join(", ", @plots), "\n";
+}
+    
+close GNUPLOT;
diff --git a/src/fwp/wme_test/schedlat.c b/src/fwp/wme_test/schedlat.c
new file mode 100644 (file)
index 0000000..f3a2237
--- /dev/null
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include <signal.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <string.h>
+#include "common.h"
+
+static inline uint64_t rdtsc(void) {
+       uint32_t hi, lo;
+       asm volatile ("rdtsc" : "=a" (lo), "=d" (hi));
+       return ((uint64_t)hi << 32) | lo;
+}
+
+void int_handler(int sig)
+{
+       exit(0);
+}
+
+static double cpu_mhz;
+
+void find_cpu_clock()
+{
+       FILE *f;
+       char line[100];
+       f = fopen("/proc/cpuinfo", "r");
+       if (!f) {
+               perror("/proc/cpuinfo");
+               exit(1);
+       }
+       while (fgets(line, sizeof(line), f)) {
+               if (strncmp(line, "cpu MHz", 7) == 0) {
+                       double mhz;
+                       int ret = sscanf(line, "cpu MHz : %lf", &mhz);
+                       if (ret != 1) {
+                               fprintf(stderr, "Can't read cpu Mhz\n");
+                               exit(1);
+                       }
+                       cpu_mhz = mhz;
+                       printf("CPU frequency: %.0lf MHz\n", cpu_mhz);
+                       break;
+               }
+       }
+       fclose(f);
+}
+
+#define CLOCK_TO_SEC(clock) ((double)(clock)/(cpu_mhz*1000.0*1000.0))
+
+void measure()
+{
+       struct timespec ts = { .tv_sec = 0, .tv_nsec = 10*1000*1000 };
+       /* uint64_t start, end; */
+       long long duration;
+       long long difference, max_difference = 0;
+       struct timespec start, end;
+       while (1) {
+               clock_gettime(CLOCK_MONOTONIC, &start);
+               nanosleep(&ts, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &end);
+               duration = timespec_sub_usec(&end, &start);
+               difference = duration - ts.tv_nsec/1000;
+               if (difference > max_difference) {
+                       max_difference = difference;
+                       printf("%lld usec\n", max_difference);
+               }
+       }
+}
+
+int main(int argc, char *argv[])
+{
+       struct sigaction act = {
+               .sa_handler = int_handler
+       };
+
+       find_cpu_clock();
+       sigaction(SIGINT, &act, NULL);
+       set_rt_prio(50);
+       measure();
+       return 0;
+}
diff --git a/src/fwp/wme_test/tester b/src/fwp/wme_test/tester
new file mode 100755 (executable)
index 0000000..8cdd562
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+TEST_DIR=tests
+OUTPUT_PREFIX=$(date +%F_%T)/
+
+while getopts t:o: opt
+do
+    case $opt in
+       t) TEST_DIR="$OPTARG";;
+       o) OUTPUT_PREFIX="$OPTARG"
+    esac
+done
+
+shift $(($OPTIND - 1)) 
+SERVER="$1"
+
+if [ -z "$SERVER" ]
+then
+    echo "Server address argument missing"
+    exit 1
+fi
+
+if echo $OUTPUT_PREFIX|grep -q "/$"
+then
+    mkdir -p $OUTPUT_PREFIX
+    [ -n "$SUDO_USER" ] && chown $SUDO_USER $OUTPUT_PREFIX
+fi
+
+find -L $TEST_DIR -type f|sort|while read F
+do
+       CMD_LINE=$(echo $F|sed -e "s/${TEST_DIR}//"|tr '/' ' ')
+       OUTPUT=$(echo $CMD_LINE|tr -s '/ -' '_')
+       echo "=== Running ./wclient $CMD_LINE"
+       ./wclient $CMD_LINE -o "${OUTPUT_PREFIX}${OUTPUT}" $SERVER
+       echo
+       sleep 1
+done
diff --git a/src/fwp/wme_test/wclient.c b/src/fwp/wme_test/wclient.c
new file mode 100644 (file)
index 0000000..1c9d75c
--- /dev/null
@@ -0,0 +1,1248 @@
+#include <errno.h>
+#include <error.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <string.h>
+#include <pthread.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include "common.h"
+#include <semaphore.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <inttypes.h>
+#include <ncurses.h>
+
+#ifdef WITH_FWP
+#include <ul_logreg.h>
+#endif
+
+#ifdef WITH_FWP
+#include <frsh.h>
+#include <fwp_res.h>
+
+/* static UL_LOG_CUST(ulogd); */
+/* static ul_log_domain_t ulogd = {UL_LOGL_MSG, "wclient"}; */
+/* UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(init_ulogd_wclient, ulogd); */
+
+#endif
+
+#define MAX_STREAMS  10 
+#define MIN_GRANULARITY 100
+
+unsigned opt_packet_size = 800;
+int opt_send_buf_size = -1;
+unsigned opt_period_usec = 10*MSEC_TO_USEC;
+char   *opt_interface;
+unsigned opt_jitter = 0;
+char    *opt_output = "delay_stats";
+unsigned opt_count_sec = 0;
+unsigned opt_def_bandwidth = 50;
+unsigned opt_def_period_msec = 0;
+int opt_granularity_usec = MIN_GRANULARITY;
+bool opt_wait_for_queue_is_full; /* Don't gather any statistics until any queue is full */
+char *opt_comment = NULL;
+bool opt_gui = false;
+
+bool some_queue_is_full = false;
+uint64_t reset_timestamp; /* [nsec] */
+
+bool some_contract_not_accepted = false;
+
+/* Locked when some queue is full to prevent multiple resets of
+   statstics. */
+pthread_mutex_t queue_full_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int ac_sockfd[AC_NUM];
+
+struct receiver {
+       bool valid;
+       pthread_t thread;
+       unsigned received, last_received;
+};
+
+struct receiver        receivers[AC_NUM];
+
+FILE* logfd;
+char* server_addr; 
+char logfname[100];
+
+/* maximal traffic delay in ms - 10 s*/
+#define MAX_DELAY_US 10000000
+
+struct delay_stat {
+       unsigned csc;           /* Client-server-client delay divided by 2 */
+       unsigned cs;            /* Client-server delay */
+       unsigned sc;            /* Server-client delay */
+};
+
+struct delay_stat delay_stats[AC_NUM][MAX_DELAY_US/MIN_GRANULARITY];
+pthread_mutex_t delay_stats_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/*struct ac_stats[AC_NUM] {
+   unsigned long int min_trans_time;
+   unsigned long int sum_trans_time;
+   struct timespec   recv_timestamp;
+   struct timespec   send_timestamp; 
+};*/
+
+struct stream {
+       /* Input parameters */
+       enum ac ac;             /*  */
+       int bandwidth_bps;      /* bits per second */
+       int jitter;             /* percent */
+       /* Mulualy exclusive input parameters */
+       int packet_size;
+       long period_usec;       /* all time units are in microseconds */
+
+       /* Internal fields */
+#ifndef WITH_FWP
+       struct sockaddr_in rem_addr;
+#else
+       frsh_send_endpoint_t endpoint;
+       frsh_receive_endpoint_t resp_endpoint;
+       frsh_vres_id_t vres, vres_rcv;
+       uint16_t resp_port;
+       struct receiver receiver;
+#endif
+
+       /* Statistics */
+       pthread_mutex_t mutex;
+       unsigned long long sent, really_sent, received;
+       long wc_delay;          /* worst-case delay  */
+};
+
+static struct cmsg_ipi {
+       struct cmsghdr cm;
+       struct in_pktinfo ipi;
+} cmsg = { {sizeof(struct cmsg_ipi), SOL_IP, IP_PKTINFO},
+          {0, }};
+int cmsg_len = 0;
+
+/*
+struct send_endpoint sepoint[] = {
+       { .ac = AC_VO, .period_usec=200*MSEC_TO_USEC, .bandwidth_bps = 34*Kbit },
+       { .ac = AC_VI, .period_usec=25*MSEC_TO_USEC, .bandwidth_bps =  480*Kbit },
+       { .ac = AC_BE, .period_usec=40*MSEC_TO_USEC, .bandwidth_bps =  300*Kbit },
+       { .ac = AC_BK, .period_usec=40*MSEC_TO_USEC, .bandwidth_bps =  300*Kbit },
+//     { .ac = AC_VI, .period_usec=17*MSEC_TO_USEC, .bandwidth_bps =  675*Kbit },
+};
+*/
+
+struct stream streams[MAX_STREAMS];
+
+unsigned int nr_streams = 0;
+
+sem_t sem_thread_finished;
+
+bool exit_flag = false;
+
+#ifdef WITH_FWP
+#define negotiate_contract_for_stream(s) negotiate_contract_for_stream_fwp(s)
+#define create_stream_endpoint(s) create_stream_endpoint_fwp(s)
+#define send_packet(s, b) send_packet_fwp(s, b)
+#define recv_packet(s, b) recv_packet_fwp(s, b)
+#define wait_for_all_threads_to_finish() wait_for_all_threads_to_finish_fwp()
+#else
+#define negotiate_contract_for_stream(s) 0
+#define create_stream_endpoint(s) create_stream_endpoint_native(s)
+#define send_packet(s, b) send_packet_native(s, b)
+#define recv_packet(s, b) recv_packet_native(s, b)
+#define wait_for_all_threads_to_finish() wait_for_all_threads_to_finish_native()
+#endif
+
+void stopper()
+{
+       int i;
+       exit_flag = true;
+
+       /* Interrupt all receivers */
+#ifdef WITH_FWP
+       for (i=0; i < nr_streams; i++) {
+               if (streams[i].receiver.valid) pthread_kill(streams[i].receiver.thread, SIGUSR1);
+       }
+#else
+       for (i=0; i < AC_NUM; i++) {
+               pthread_kill(receivers[i].thread, SIGUSR1);
+       }       
+#endif
+}
+
+void stream_to_text(char *stream_desc, size_t n, struct stream *stream, long long useconds)
+{
+       char buf[3][12];
+       char real[100];
+
+       if (useconds) {
+               snprintf(real, sizeof(real), "; real: %s sent %lld (%lld/s), received %lld (%lld/s)",
+                        bandwidth_to_text(buf[0], (long long)stream->really_sent*stream->packet_size*8*SEC_TO_USEC/useconds),
+                        stream->sent, stream->sent*SEC_TO_USEC/useconds,
+                        stream->received, stream->received*SEC_TO_USEC/useconds);
+       } else {
+               real[0]=0;
+       }
+       
+       snprintf(stream_desc, n, "%"PRIdPTR": %s %s (%d bytes per %s +-%s, %d packets/s)%s",
+                stream-streams, ac_to_text[stream->ac], bandwidth_to_text(buf[0], stream->bandwidth_bps),
+                stream->packet_size, usec_to_text(buf[1], stream->period_usec),
+                usec_to_text(buf[2], stream->jitter*stream->period_usec/100),
+                (int)(SEC_TO_USEC/stream->period_usec), real);
+}
+
+void save_results(int argc, char *argv[], int useconds)
+{
+       int ac, i, maxi;
+       const int mini = 3000/opt_granularity_usec;
+       bool allzeros;
+       unsigned send_count[AC_NUM];
+
+       fprintf(stderr, "Writing data to %s... ", logfname);
+       fflush(stderr);
+
+       fprintf(logfd, "# Invoked as: ");
+       for (i=0; i<argc; i++) fprintf(logfd, "%s ", argv[i]);
+       if (opt_comment) {
+               fprintf(logfd, "(%s)", opt_comment);
+       }
+       fprintf(logfd, "\n");
+
+       if (useconds/SEC_TO_USEC != opt_count_sec) {
+               char buf[20];
+               usec_to_text(buf, useconds);
+               fprintf(logfd, "# Data gathered for %s.\n", buf);
+       }
+               
+       for (i = 0; i < nr_streams; i++) {
+               char stream_desc[200];
+               stream_to_text(stream_desc, sizeof(stream_desc), &streams[i], useconds);
+               fprintf(logfd, "# Stream %s\n", stream_desc);
+       }
+
+       /* Find maximal delay */
+       allzeros = true;
+       for (maxi = MAX_DELAY_US/opt_granularity_usec - 1; maxi >= 0; maxi--) {
+               for (ac = 0; ac < AC_NUM; ac++) {
+                       if ((delay_stats[ac][maxi].csc != 0) ||
+                           (delay_stats[ac][maxi].cs != 0) ||
+                           (delay_stats[ac][maxi].sc != 0))
+                               allzeros = false;
+               }
+               if (!allzeros) break;
+       }
+       maxi++;
+       if (maxi < mini) maxi = mini;
+
+       /* Calculate total number of sent packets per AC */
+       memset(send_count, 0, sizeof(send_count));
+       for (i = 0; i < nr_streams; i++) {
+               ac = streams[i].ac;
+               send_count[ac] += streams[i].sent;
+       }
+
+#if 0
+       /* Write pdf */
+       for ( i = 0 ; i < maxi; i++) {
+               fprintf(logfd,"\n%f", i*opt_granularity_usec/1000.0);
+               for (ac = 0; ac < AC_NUM; ac++) { 
+                       if (sum[ac])
+                               val = (double)delay_stats[ac][i]*100.0 / sum[ac];
+                       else val = -1; /* Don't display this ac */
+                       fprintf(logfd," %lf", val);
+               }
+       }
+       
+       fprintf(logfd,"\n\n");
+#endif
+       
+       fprintf(logfd,"## Format: msec csc%% cs%% sc%%\n");
+
+       /* Write PDF */
+       for (ac = 0; ac < AC_NUM; ac++) {
+               struct delay_stat integral = {0,0,0}, last = {-1,-1,-1};
+
+               fprintf(logfd,"%f %f %f %f\n", 0.0, 0.0, 0.0, 0.0);
+
+               if (send_count[ac] != 0) {
+                       i=0;
+                       while ((delay_stats[ac][i].csc == 0) &&
+                              (delay_stats[ac][i].cs == 0) &&
+                              (delay_stats[ac][i].sc == 0)) i++;
+               
+                       for (i++; i < maxi+1; i++) {
+                               if (memcmp(&last, &integral, sizeof(last))) {
+                                       char buf[3][20];
+                                       snprintf(buf[0], sizeof(buf[0]), "%f", (double)integral.csc*100.0 / send_count[ac]);
+                                       snprintf(buf[1], sizeof(buf[1]), "%f", (double)integral.cs *100.0 / send_count[ac]);
+                                       snprintf(buf[2], sizeof(buf[2]), "%f", (double)integral.sc *100.0 / send_count[ac]);
+                                                
+                                       fprintf(logfd,"%f %s %s %s\n", i*opt_granularity_usec/1000.0,
+                                               integral.csc != last.csc ? buf[0] : "-",
+                                               integral.cs  != last.cs  ? buf[1] : "-",
+                                               integral.sc  != last.sc  ? buf[2] : "-"
+                                               );
+                                       last = integral;
+                               }
+                               if (i>0) {
+                                       integral.csc += delay_stats[ac][i-1].csc;
+                                       integral.sc  += delay_stats[ac][i-1].sc;
+                                       integral.cs  += delay_stats[ac][i-1].cs;
+                               }
+                       }
+               }
+               fprintf(logfd,"\n\n");
+       }
+       
+       fprintf(stderr, "finished.\n");
+       fclose(logfd);
+
+       exit(0);
+}
+
+int create_ac_socket(intptr_t ac) 
+{
+       int sockfd;
+       unsigned int yes=1, tos;
+
+
+       if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+       {
+               error(0, errno, "Unable to open socket");
+               return -1;
+       }
+       if (fcntl(sockfd, F_SETFL, O_NONBLOCK) != 0) {
+               error(0, errno, "set non-blocking socket");
+               return -1;
+       }
+       if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
+               error(0, errno, "Unable to set socket");
+               return -1;
+       }
+
+       if (opt_send_buf_size >= 0) {
+               if (setsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,&opt_send_buf_size,sizeof(opt_send_buf_size)) == -1) {
+                       error(0, errno, "Unable to set socket buffer size");
+                       return -1;
+               }
+       }
+
+       
+       //tos = ((AC_NUM - ac) *2 - 1)*32;
+       tos = ac_to_tos[ac];
+       if (setsockopt(sockfd, SOL_IP, IP_TOS, &tos, sizeof(tos))) {
+               error(0, errno, "Unable to set TOS");
+               close(sockfd);
+               return -1;
+       }
+
+       return sockfd;
+}
+
+void empty_handler()
+{
+}
+
+void reset_statistics()
+{
+       int i;
+       struct timespec ts;
+       for (i = 0; i < nr_streams; i++) {
+               pthread_mutex_lock(&streams[i].mutex);
+               streams[i].sent = 0;
+               streams[i].really_sent = 0;
+               streams[i].received = 0;
+               pthread_mutex_unlock(&streams[i].mutex);
+       }
+       pthread_mutex_lock(&delay_stats_mutex);
+       clock_gettime(CLOCK_REALTIME, &ts);
+       reset_timestamp = ts.tv_sec*1000000000LL + ts.tv_nsec;
+       memset(delay_stats, 0, sizeof(delay_stats));
+       pthread_mutex_unlock(&delay_stats_mutex);
+}
+
+#ifndef WITH_FWP
+int recv_packet_native(intptr_t ac, struct msg_t *msg)
+{
+       int     mlen, ret;
+       fd_set fdset;
+       struct  sockaddr_in rem_addr;
+       unsigned int rem_addr_length; 
+
+       FD_ZERO(&fdset);
+       FD_SET(ac_sockfd[ac], &fdset);
+        rem_addr_length = sizeof(rem_addr);
+       mlen = -1;
+       while (!exit_flag) {
+               ret = select(ac_sockfd[ac]+1, &fdset, NULL, NULL, NULL);
+               if (ret < 0) {
+                       if (errno == EINTR) continue;
+                       error(0, errno, "receiver select");
+                       return -1;
+               }
+               mlen = recvfrom(ac_sockfd[ac], msg, sizeof(*msg), 0,
+                               (struct sockaddr*)&rem_addr, &rem_addr_length);
+               break;
+       }
+       return mlen;
+}
+#else
+int recv_packet_fwp(struct stream *stream, struct msg_t *msg)
+{
+       int ret;
+       size_t mlen;
+
+       ret = frsh_receive_sync(stream->resp_endpoint, msg, sizeof(*msg), &mlen, NULL);
+       return mlen;
+}
+#endif
+
+void* receiver(void* arg)
+{
+       struct msg_t    msg;
+       long long int trans_time_usec, client_to_server_usec, server_to_client_usec;
+       long long int min_trans_time;
+       struct timespec ts;
+       uint64_t send_timestamp, server_timestamp, recv_timestamp;
+       int     mlen;
+       intptr_t ac;
+       
+       min_trans_time = ~0;
+       
+       block_signals();
+       set_rt_prio(99);
+
+       while (!exit_flag) {
+#ifdef WITH_FWP
+               struct stream *stream = arg;
+               ac = stream->ac;
+               mlen = recv_packet_fwp(stream, &msg);
+#else
+               ac = (intptr_t)arg;
+               mlen = recv_packet_native(ac, &msg);
+#endif
+               if (mlen < 0) {
+                       if (errno != EINTR)
+                               error(0, errno, "receive_packet error");
+                       goto out;
+               }       
+               clock_gettime(CLOCK_REALTIME,&ts);
+               recv_timestamp = ts.tv_sec*1000000000LL + ts.tv_nsec;
+               send_timestamp = msg.send_timestamp;
+               server_timestamp = msg.sendback_timestamp;
+
+               /* Check whether this message was sent after reset_statistics() */
+
+               if (send_timestamp < reset_timestamp) {
+                       continue; /* If so, don't count it */
+               }
+
+               trans_time_usec = (recv_timestamp - send_timestamp) / 2 / 1000;
+               client_to_server_usec = (server_timestamp - send_timestamp) / 1000;
+               server_to_client_usec = (recv_timestamp - server_timestamp) / 1000;
+
+               pthread_mutex_lock(&delay_stats_mutex);
+               if (trans_time_usec < MAX_DELAY_US && trans_time_usec >= 0) {
+                       delay_stats[ac][trans_time_usec/opt_granularity_usec].csc++;
+               }
+               if (client_to_server_usec < MAX_DELAY_US && client_to_server_usec >= 0) {
+                       delay_stats[ac][client_to_server_usec/opt_granularity_usec].cs++;
+               }
+               if (server_to_client_usec < MAX_DELAY_US && server_to_client_usec >= 0) {
+                       delay_stats[ac][server_to_client_usec/opt_granularity_usec].sc++;
+               }
+               pthread_mutex_unlock(&delay_stats_mutex);
+
+               if (trans_time_usec > streams[msg.stream].wc_delay) {
+                       streams[msg.stream].wc_delay = trans_time_usec;
+               }
+               receivers[ac].received++;
+               
+               pthread_mutex_lock(&streams[msg.stream].mutex);
+               streams[msg.stream].received++;
+               pthread_mutex_unlock(&streams[msg.stream].mutex);
+       
+               /*if (trans_time_nsec < min_trans_time) 
+                       min_trans_time = trans_time_nsec;*/
+               /*printf("seqn= %lu tos= %d start= %lu(s).%lu(ns)"\
+                        "stop= %lu(s).%lu(ns)\n trans_time = %lums\n",\
+                        msg.seqn, msg.tos, send_timestamp.tv_sec,\
+                        send_timestamp.tv_nsec,recv_timestamp.tv_sec,\
+                        recv_timestamp.tv_nsec, trans_time_msec); */
+       }
+out:
+       sem_post(&sem_thread_finished);
+       return NULL;
+}
+
+/** 
+ * Send a packet.
+ * 
+ * @return -1 in case of error, 1 in case of sucessfull send and 0
+ *        when all buffers are full.
+ */
+#ifndef WITH_FWP
+static inline int 
+send_packet_native(struct stream* stream, union msg_buff* buff)
+{
+       struct iovec  iov;
+       struct msghdr msg;
+
+       iov.iov_base = buff;
+       iov.iov_len = stream->packet_size;
+       msg.msg_name = (void*)&stream->rem_addr;
+       msg.msg_namelen = sizeof(stream->rem_addr);
+       msg.msg_iov = &iov;
+       msg.msg_iovlen = 1;
+       msg.msg_flags = 0;
+       msg.msg_control = &cmsg;
+       msg.msg_controllen = cmsg_len;
+
+       int ret = 1;
+       
+       while (sendmsg(ac_sockfd[stream->ac], &msg, 0) < 0) {
+               if (errno == EINTR) continue;
+               if (errno == EAGAIN) {
+                       if (opt_wait_for_queue_is_full && 
+                           !some_queue_is_full && 
+                           /* We use mutex as atomic test and set */
+                           (pthread_mutex_trylock(&queue_full_mutex) != EBUSY)) {
+                               some_queue_is_full = true;
+                               reset_statistics();
+                       }
+                       ret = 0;
+                       break;
+               } else {
+                       error(0, errno, "Error while sending");
+                       ret = -1;
+                       break;
+               }
+       }
+       return ret;
+}
+#else
+static inline int 
+send_packet_fwp(struct stream* stream, union msg_buff* buff)
+{
+       int ret = 0;
+
+       buff->msg.resp_port = htons(stream->resp_port);
+       ret = frsh_send_async(stream->endpoint, buff, stream->packet_size);
+       if (ret) {
+               char msg[1024];
+               frsh_strerror(ret, msg, sizeof(msg));
+               fprintf(stderr, "frsh_send error: %s\n", msg);
+       }
+       return (ret == 0) ? 0 : -1;
+}
+#endif
+
+static inline void
+wait_for_next_send(struct stream* stream, struct timespec *last_send_time)
+{
+       struct timespec time_to_wait, current_time, period, interval;
+       unsigned delay_usec, period_usec = stream->period_usec;
+
+       /*           |~~~+~~~| jitter interval (width = 2*stream->jitter percentage from period)*/
+       /* |-------------|     nominal period*/
+       if (stream->jitter) {
+               delay_usec = period_usec*(100-stream->jitter)/100
+                       + rand() % (2*period_usec*stream->jitter/100);
+       } else {
+               delay_usec = period_usec;
+       }
+       period.tv_nsec = USEC_TO_NSEC*(delay_usec%SEC_TO_USEC);
+       period.tv_sec = delay_usec/SEC_TO_USEC;
+       
+       timespec_add(&time_to_wait, last_send_time, &period);
+       clock_gettime(CLOCK_MONOTONIC,&current_time);
+       timespec_sub(&interval,&time_to_wait,&current_time);
+       if (interval.tv_sec >= 0) {
+               nanosleep(&interval,NULL);
+               *last_send_time = time_to_wait;
+       } else {
+               *last_send_time = current_time;
+       }
+}
+
+
+void* sender(void* arg)
+{
+       union msg_buff buff;
+       unsigned long int seqn;
+       struct stream* stream = (struct stream*) arg;
+       struct timespec timer = { 0, 0 }, ts;
+       int ret;
+
+       if (!opt_gui) {
+               char stream_desc[100];
+               stream_to_text(stream_desc, sizeof(stream_desc), stream, 0);
+               printf("%s\n", stream_desc);
+       }
+       if (stream->bandwidth_bps == 0)
+               goto out;
+
+       seqn = 0;
+       
+       block_signals();
+       set_rt_prio(90-stream->ac);
+
+       while (!exit_flag) {
+               wait_for_next_send(stream, &timer);
+
+/*             buff.msg.seqn = seqn++; */
+/*             buff.msg.tos = ac_to_tos[stream->ac]; */
+               buff.msg.stream = stream-streams;
+               
+               clock_gettime(CLOCK_REALTIME,&ts);
+               buff.msg.send_timestamp = ts.tv_sec*1000000000LL + ts.tv_nsec;
+
+               ret = send_packet(stream, &buff);
+               if (ret < 0) {
+                       stopper();
+                       goto out;
+               }
+
+               pthread_mutex_lock(&stream->mutex);
+               stream->sent++;
+               if (ret > 0)
+                       stream->really_sent++;
+               pthread_mutex_unlock(&stream->mutex);
+
+#ifdef DEBUG
+               printf("%d", stream->ac);
+               fflush(stdout);
+#endif
+
+       }
+out:
+       sem_post(&sem_thread_finished);
+       return NULL;
+}
+
+#ifdef WITH_FWP
+static int negotiate_contract_for_stream_fwp(struct stream *stream)
+{
+       frsh_contract_t contract;
+       int ret;
+       frsh_rel_time_t budget, period, deadline;
+
+       /* Contract for client->server stream */
+       frsh_contract_init(&contract);
+       frsh_contract_set_resource_and_label(&contract, FRSH_RT_NETWORK, FRSH_NETPF_FWP, NULL);
+       frsh_network_bytes_to_budget(FRSH_NETPF_FWP, stream->packet_size, &budget);
+       period = frsh_usec_to_rel_time(stream->period_usec);
+       frsh_contract_set_basic_params(&contract, &budget, &period, FRSH_WT_BOUNDED, FRSH_CT_REGULAR);
+       deadline = frsh_usec_to_rel_time(3*stream->period_usec);
+       frsh_contract_set_timing_reqs(&contract, false, &deadline);
+       
+       ret = frsh_contract_negotiate(&contract, &stream->vres);
+       frsh_contract_destroy(&contract);
+       if (ret != 0) {
+               stream->vres = NULL;
+               fprintf(stderr, "Send contract was not accepted\n");
+               return ret;
+       }
+
+       /* Contract for server->client stream */
+       /* TODO: Use group negotiation for these two contracts */
+       frsh_contract_init(&contract);
+       frsh_contract_set_resource_and_label(&contract, FRSH_RT_NETWORK, FRSH_NETPF_FWP, NULL);
+       frsh_network_bytes_to_budget(FRSH_NETPF_FWP, stream->packet_size, &budget);
+       period = frsh_usec_to_rel_time(stream->period_usec);
+       frsh_contract_set_basic_params(&contract, &budget, &period, FRSH_WT_BOUNDED, FRSH_CT_DUMMY);
+       deadline = frsh_usec_to_rel_time(3*stream->period_usec);
+       frsh_contract_set_timing_reqs(&contract, false, &deadline);
+
+       ret = frsh_contract_negotiate(&contract, &stream->vres_rcv);
+       frsh_contract_destroy(&contract);
+       if (ret != 0) {
+               fprintf(stderr, "Receive contract was not accepted\n");
+               return ret;
+       }
+
+       /* We don't use the vres at server, since the server doesn't
+        * know the parameters. Instread, server uses plain
+        * sockets. */
+       
+       return ret;
+}
+#endif
+
+#ifdef WITH_FWP
+static void create_stream_endpoint_fwp(struct stream *stream)
+{
+/*     fwp_endpoint_attr_t  attr; */
+       int ret;
+       struct hostent* ph;
+       frsh_contract_t c;
+       fres_block_fwp_sched *fwp_sched;
+
+       frsh_vres_get_contract(stream->vres, &c);
+       fwp_sched = fres_contract_get_fwp_sched(c);
+
+       stream->ac = fwp_sched->ac_id;
+
+/*     fwp_endpoint_attr_init(&attr); */
+/*     fwp_endpoint_attr_setreliability(&attr, FWP_EPOINT_BESTEFFORT); */
+
+       ph = gethostbyname(server_addr);
+       if (ph && ph->h_addr_list[0]) {
+               struct in_addr *a = (struct in_addr *)(ph->h_addr_list[0]);
+               frsh_send_endpoint_protocol_info_t    spi = { NULL, 0 };
+               frsh_receive_endpoint_protocol_info_t rpi = { NULL, 0 };
+               frsh_endpoint_queueing_info_t qi = { .queue_size=0, .queue_policy=FRSH_QRP_OLDEST };
+               ret = frsh_send_endpoint_create(FRSH_NETPF_FWP, a->s_addr, BASE_PORT + stream->ac, 
+                                               spi, &stream->endpoint);
+               if (ret < 0) error(1, errno, "frsh_send_endpoint_create()");
+               
+               ret = frsh_send_endpoint_bind(stream->vres, stream->endpoint);
+               if (ret != 0) error(1, errno, "frsh_send_endpoint_bind");
+
+               ret = frsh_receive_endpoint_create(FRSH_NETPF_FWP, 0, qi, rpi,
+                                                  &stream->resp_endpoint);
+               if (ret != 0) error(1, errno, "fwp_receive_endpoint_create");
+               
+               unsigned int port;
+               frsh_receive_endpoint_get_params(stream->resp_endpoint, NULL, &port, NULL, NULL);
+               stream->resp_port = port;
+
+               ret = pthread_create(&stream->receiver.thread, NULL, receiver, (void*)stream);
+               if (ret) error(1, ret, "Error while creating receiver");
+               
+               stream->receiver.valid = true;
+       }
+       else {
+               error(1, errno, "gethostbyname(%s)", server_addr);
+       }
+
+}
+#else
+static void create_stream_endpoint_native(struct stream *stream)
+{
+       struct hostent* ph;
+
+       memset(&stream->rem_addr,0, sizeof(stream->rem_addr));
+
+       stream->rem_addr.sin_family = AF_INET;
+       ph = gethostbyname(server_addr);
+       if (ph)
+               stream->rem_addr.sin_addr = *((struct in_addr *)ph->h_addr);
+       else {
+               error(1, errno, "gethostbyname(%s)", server_addr);
+       }
+       stream->rem_addr.sin_port = htons(BASE_PORT + stream->ac);
+}
+#endif
+
+static inline void
+calc_stream_params(struct stream *stream)
+{
+       int packet_size;
+       unsigned period_usec;
+       int bandwidth;
+       int ret;
+
+       /* If some parameters are not set explicitely, use default values. */
+       if (stream->bandwidth_bps < 0) stream->bandwidth_bps = opt_def_bandwidth * Kbit;
+       if (stream->packet_size < 0) stream->packet_size = opt_packet_size;
+       if (stream->period_usec < 0) stream->period_usec = opt_def_period_msec * MSEC_TO_USEC;
+
+       bandwidth = stream->bandwidth_bps;
+
+       /* Avoid arithmetic exception. Server thread will exit if
+          stream->bandwidth_bps == 0. */
+       if (bandwidth == 0) bandwidth = 1;
+
+       if (stream->packet_size) {
+               packet_size = stream->packet_size;
+               period_usec = SEC_TO_USEC*packet_size*8/bandwidth;
+               if (period_usec == 0) period_usec = 1;
+       } else if (stream->period_usec) {
+               period_usec = stream->period_usec;
+               packet_size = (long long)bandwidth/8 * period_usec/SEC_TO_USEC;
+       } else {
+               char buf[200];
+               stream_to_text(buf, sizeof(buf), stream, 0);
+               error(1, 0, "Neither packet size nor period was specified for a stream %s", buf);
+       }
+
+       if (packet_size < sizeof(struct msg_t)) {
+               error(1, 0, "Packet size too small (min %zd)", sizeof(struct msg_t));
+       }
+
+       stream->packet_size = packet_size;
+       stream->period_usec = period_usec;
+       stream->jitter = opt_jitter;
+
+       ret = negotiate_contract_for_stream(stream);
+       if (ret == 0) {
+               create_stream_endpoint(stream);
+       } else {
+               char buf[200];
+               stream_to_text(buf, sizeof(buf), stream, 0);
+               fprintf(stderr, "Contract hasn't been accepted:\n%s\n", buf);
+               stream->bandwidth_bps = 0;
+               some_contract_not_accepted = true;
+       }
+}
+
+/** 
+ * Parse -b parameter.
+ * 
+ * @param params String to parse
+ * 
+ * @return NULL in case of success, pointer to a problematic character
+ *        on error.
+ */
+char* parse_bandwidths(char *params)
+{
+       struct stream *sp = &streams[nr_streams];
+
+       while (*params && nr_streams < MAX_STREAMS) {
+               char *ac_ids[AC_NUM] = { [AC_VO]="VO", [AC_VI]="VI", [AC_BE]="BE", [AC_BK]="BK" };
+               int i;
+               char *next_char;
+
+               if (strlen(params) < 2)
+                       return params;
+               for (i=0; i<AC_NUM; i++) {
+                       if (strncmp(params, ac_ids[i], 2) == 0) {
+                               sp->ac = i;
+                               params+=strlen(ac_ids[i]);
+                               break;
+                       }
+               }
+               if (i==AC_NUM)
+                       return params;
+
+               long bw;
+               if (*params == ':') {
+                       params++;
+
+                       bw = strtol(params, &next_char, 10);
+                       if (next_char == params)
+                               return params;
+                       params = next_char;
+               } else
+                       bw = -1;
+               
+               sp->bandwidth_bps = bw*Kbit;
+
+               long period = 0;
+               long packet_size = 0;
+               if (*params == '@') {
+                       params++;
+                       period = strtol(params, &next_char, 10);
+                       if (period == 0)
+                               return params;
+                       params = next_char;
+               }
+               else {
+                       if (*params == '/') {
+                               params++;
+                               packet_size = strtol(params, &next_char, 10);
+                               if (packet_size == 0)
+                                       return params;
+                               params = next_char;
+                       } else {
+                               packet_size = -1; 
+                               period = -1;
+                       }
+               }
+               sp->period_usec = period*MSEC_TO_USEC;
+               sp->packet_size = packet_size;
+
+               
+
+               if (*params != '\0' && *params != ',')
+                       return params;
+               nr_streams++;
+               sp++;
+               if (*params == ',')
+                       params++;
+       }
+       return NULL;
+}
+
+#ifdef WITH_FWP
+void wait_for_all_threads_to_finish_fwp(void)
+{
+       int i;
+       /* wait for all threads to finish */
+       for (i=0; i < 2*nr_streams; i++) {
+               sem_wait(&sem_thread_finished);
+       }
+}
+#else
+void wait_for_all_threads_to_finish_native(void)
+{
+       int i;
+       /* Wait for all threads to finish */
+       for (i=0; i < nr_streams + AC_NUM; i++) {
+               sem_wait(&sem_thread_finished);
+       }
+}
+#endif
+
+WINDOW *logwin;
+
+#if 0
+struct log_params {
+       ul_log_domain_t *domain;
+       int level;
+       const char *format;
+       va_list ap;
+};
+
+
+int locked_log(WINDOW *logwin, void *arg)
+{
+       struct log_params *p = arg;
+       if(!(p->level&UL_LOGL_CONT)) {
+               p->level&=UL_LOGL_MASK;
+               if(p->level)
+                       wprintw(logwin,"<%d>", p->level);
+               if(p->domain && p->domain->name)
+                       wprintw(logwin,"%s: ",p->domain->name);
+       }
+       vwprintw(logwin, p->format, p->ap);
+       wnoutrefresh(logwin);
+       return 0;
+}
+
+void
+wclient_log_fnc(ul_log_domain_t *domain, int level,
+               const char *format, va_list ap)
+{
+       struct log_params p = {
+               .domain = domain,
+               .level = level,
+               .format = format,
+       };
+       va_copy(p.ap, ap);
+       va_end(ap);
+
+       use_window(logwin, locked_log, (void*)&p);
+}
+#endif
+
+
+void init_gui()
+{
+       if (opt_gui) {
+               initscr();
+               cbreak();
+               noecho();
+/*             nonl(); */
+/*             intrflush(stdscr, FALSE); */
+/*             keypad(stdscr, TRUE); */
+
+               logwin = newwin(0, 0, LINES/2, 0);
+               if (logwin) {
+                       scrollok(logwin, TRUE);
+/*             ul_log_redir(wclient_log_fnc, 0); */
+               }
+       }
+}
+
+void end_gui()
+{
+       if (opt_gui) {
+               endwin();
+               if (logwin) {
+/*             ul_log_redir(NULL, 0); */
+               }
+       }
+}
+
+
+#define addfield(title, format, ...)                                   \
+       move(y, x);                                                     \
+       x+=strlen(title)+1;                                             \
+       if (i == 0) addstr(title);                                      \
+       else {                                                          \
+               snprintf(str, sizeof(str), format, __VA_ARGS__);        \
+               addstr(str);                                            \
+       }
+
+void print_status_gui(int seconds)
+{
+       int i;
+       char str[200], s1[20];
+       int x = 0, y;
+       struct stream *s = NULL;
+       
+       for (i = 0; i <= nr_streams; i++) {
+               if (i>0) s = &streams[i-1];
+               y=i;
+               x=0;
+               addfield("Stream", "%d", i);
+               addfield("Bandwidth", "%s", bandwidth_to_text(s1, s->bandwidth_bps));
+               addfield("Packet size", "%d bytes", s->packet_size);
+               addfield("Period   ", "%s", usec_to_text(s1, s->period_usec));
+               addfield("AC   ", "%s", ac_to_text[s->ac]);
+               addfield("Worst-case delay", "%s", usec_to_text(s1, s->wc_delay));
+               addfield("Received responses", "%lld", s->received);
+       }
+       wnoutrefresh(stdscr);
+       doupdate();
+}
+
+void print_status_nogui(int seconds)
+{
+       int ac;
+       fprintf(stderr, "\r%3ds", seconds);
+       for (ac = 0; ac < AC_NUM; ac++) {
+               int delta = receivers[ac].received - receivers[ac].last_received;
+               receivers[ac].last_received = receivers[ac].received;
+               fprintf(stderr, " %s %5d %4d/s", ac_to_text[ac], receivers[ac].received, delta);
+       }
+       fflush(stderr);
+}
+
+#ifdef WITH_FWP
+int print_log_domain(ul_log_domain_t *domain, void *context)
+{
+       printf("%s = %d\n", domain->name, domain->level);
+       return 0;
+}
+#endif
+int main(int argc, char *argv[])
+{
+       int i, rc, frames, seconds;
+       pthread_attr_t attr;
+       pthread_t thread;
+       char opt;
+
+
+       while ((opt = getopt(argc, argv, "B:b:C:c:Gg:I:j:l:o:qQ:s:T:")) != -1) {
+               switch (opt) {
+                       case 'B':
+                               opt_def_bandwidth = atoi(optarg);
+                               break;
+                       case 'b': {
+                               char *errpos;
+                               errpos = parse_bandwidths(optarg);
+                               if (errpos != NULL) {
+                                       if (*errpos == '\0')
+                                               error(1, 0, "Bandwidth parse error - string to short");
+                                       else
+                                               error(1, 0, "Bandwidth parse error at '%s'", errpos);
+                               }
+                               break;
+                       }
+                       case 'C':
+                               opt_comment = optarg;
+                               break;
+                       case 'c':
+                               opt_count_sec = atoi(optarg);
+                               break;
+                       case 'G':
+                               opt_gui = true;
+                               break;
+                       case 'g':
+                               opt_granularity_usec = atoi(optarg);
+                               if (opt_granularity_usec < MIN_GRANULARITY) {
+                                       error(1, 0, "Granulatiry too small (min %d)", MIN_GRANULARITY);
+                               }
+                               break;
+                       case 'I':
+                               opt_interface = optarg;
+                               break;
+                       case 'j':
+                               opt_jitter = atoi(optarg);
+                               break;
+#ifdef WITH_FWP
+                       case 'l':
+                               if (*optarg == '?') {
+                                       ul_logreg_for_each_domain(print_log_domain, NULL);
+                                       exit(0);
+                               }
+                               {
+                                       int ret;
+                                       ret = ul_log_domain_arg2levels(optarg);
+                                       if (ret) 
+                                               error(1, EINVAL, "Error parsing -l argument at char %d\n", ret);
+                               }
+                               break;
+#endif
+                       case 'o':
+                               opt_output = optarg;
+                               break;
+                       case 'Q':
+                               opt_send_buf_size = atoi(optarg);
+                               break;
+                       case 'q':
+                               opt_wait_for_queue_is_full = true;
+                               break;
+                       case 's':
+                               opt_packet_size = atoi(optarg);
+                               break;
+                       case 'T':
+                               opt_def_period_msec = atoi(optarg);
+                               break;
+                       default:
+                               fprintf(stderr, "Usage: %s [ options ] server_addr\n\n", argv[0]);
+                               fprintf(stderr, "Options:\n");
+                               fprintf(stderr, "    -B  default bandwidth for -b option [kbit]\n");
+                               fprintf(stderr, "    -b  bandwidth of streams (VO|VI|BE|BK)[:<kbit>][@<msec> or /<bytes>][,...]\n");
+                               fprintf(stderr, "    -C  comment (added to header)\n");
+                               fprintf(stderr, "    -c  count (number of seconds to run)\n");
+                               fprintf(stderr, "    -g  histogram granularity [usec]\n");
+                               fprintf(stderr, "    -G  show status in textual GUI\n");
+                               fprintf(stderr, "    -I  <interface> send packets from this interface\n");
+#ifdef WITH_FWP
+                               fprintf(stderr, "    -l  <loglevel> uLUt logging levels\n");
+#endif
+                               fprintf(stderr, "    -j  send jitter (0-100) [%%]\n");
+                               fprintf(stderr, "    -o  output filename (.dat will be appended)\n");
+                               fprintf(stderr, "    -q  gather statistics only after some queue becomes full\n");
+                               fprintf(stderr, "    -Q  <bytes> set size for socket send buffers\n");
+                               fprintf(stderr, "    -s  size of data payload in packets [bytes] (default: %d)\n", opt_packet_size);
+                               fprintf(stderr, "    -T  default period for -b option [msec]\n");
+                               exit(1);
+               }
+       }
+       if (opt_packet_size && opt_def_period_msec) {
+               error(1, 0, "Error: Nonzero -T and -s can't be used together!");
+       }
+
+       if (optind < argc) {
+               server_addr = argv[optind];
+       } else {
+               error(1, 0, "Expected server address argument");
+       }
+
+       if (nr_streams == 0)
+               parse_bandwidths("BE");
+               
+       pthread_attr_init(&attr);
+
+       snprintf(logfname, sizeof(logfname), "%s.dat", opt_output);
+
+       if ((logfd = fopen(logfname,"w+")) == NULL) {
+               error(1, errno ,"Can not open %s", logfname);
+       }
+       if (signal(SIGTERM, stopper) == SIG_ERR) {
+               error(1, errno, "Error in signal registration");
+       }
+               
+       if (signal(SIGINT, stopper) == SIG_ERR) {
+               error(1, errno, "Signal handler registration error");
+       }
+
+       struct sigaction sa;
+       sa.sa_handler = empty_handler;
+       sa.sa_flags = 0;        /* don't restart syscalls */
+
+       if (sigaction(SIGUSR1, &sa, NULL) < 0) {
+               error(1, errno, "sigaction error");
+       }
+
+       sem_init(&sem_thread_finished, 0, 0);
+
+       reset_statistics();
+
+#ifdef WITH_FWP
+       //ul_log_domain_arg2levels("6");
+       rc = frsh_init();
+       if (rc != 0) {
+               error(1, errno, "FWP initialization failed");
+       }
+#else
+       intptr_t ac;
+       /* create four receivers each per AC */
+       for (ac = AC_NUM - 1; ac >= 0; ac--) {
+               ac_sockfd[ac] = create_ac_socket(ac);
+               if (ac_sockfd[ac] < 0) {
+                       return 1;
+               }
+               rc = pthread_create(&receivers[ac].thread, &attr, receiver, (void*) ac);
+               if (rc) {
+                       error(1, rc, "Error while creating receiver");
+               }
+               receivers[ac].valid = true;
+       }               
+#endif
+
+                       
+       if (opt_interface) {
+               struct ifreq ifr;
+
+               memset(&ifr, 0, sizeof(ifr));
+               strncpy(ifr.ifr_name, opt_interface, IFNAMSIZ-1);
+               if (ioctl(ac_sockfd[AC_VO], SIOCGIFINDEX, &ifr) < 0) {
+                       error(1, 0, "unknown iface %s", opt_interface);
+               }
+               cmsg.ipi.ipi_ifindex = ifr.ifr_ifindex;
+               cmsg_len = sizeof(cmsg);
+       }
+       /* create sendpoints */
+       for (i = 0; i < nr_streams; i++) {
+               struct stream *s = &streams[i];
+               pthread_mutex_init(&s->mutex, NULL);
+               calc_stream_params(s);
+               rc = pthread_create(&thread, &attr, sender, (void*) s);
+               if (rc) error(1, rc, "Error while creating sender");
+       }
+
+       if (some_contract_not_accepted) {
+               stopper();
+       } else {
+               init_gui();
+
+               seconds = 1;
+               frames=0;
+               while (!exit_flag) {
+                       if (opt_gui) {
+                               usleep(40000);
+                               frames++;
+                               if (frames>=25) {
+                                       seconds++;
+                                       frames = 0;
+                               }
+                               print_status_gui(seconds);
+                       } else {
+                               sleep(1);
+                               seconds++;
+                               print_status_nogui(seconds);
+                       }
+
+                       if (seconds == opt_count_sec)
+                               stopper();
+               }
+       }
+
+       end_gui();
+
+       fprintf(stderr, "\nWaiting for threads to finish\n");
+       wait_for_all_threads_to_finish();
+
+#ifdef WITH_FWP
+       for (i=0; i < nr_streams; i++) {
+               if (streams[i].vres)
+                       frsh_contract_cancel(streams[i].vres);
+               if (streams[i].vres_rcv)
+                       frsh_contract_cancel(streams[i].vres_rcv);
+       }
+#endif
+
+       struct timespec ts;
+       uint64_t end_timestamp, measure_length;
+       clock_gettime(CLOCK_REALTIME,&ts);
+       end_timestamp = ts.tv_sec*1000000000LL+ts.tv_nsec;
+       measure_length = end_timestamp - reset_timestamp;
+
+       save_results(argc, argv, measure_length/1000);
+
+       return 0;
+}
diff --git a/src/fwp/wme_test/wserver.c b/src/fwp/wme_test/wserver.c
new file mode 100644 (file)
index 0000000..1b716d2
--- /dev/null
@@ -0,0 +1,238 @@
+#include <stdlib.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <signal.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <string.h>
+#include <pthread.h>
+#include "common.h"
+#include <stdbool.h>
+
+bool opt_same_interface = false;
+
+static int ac_sockfd[AC_NUM];
+
+struct receiver {
+       unsigned received, last_received;
+} receivers[AC_NUM];
+
+
+void stopper()
+{
+       int i;
+
+       for (i = 0; i < AC_NUM; i++) 
+               close(ac_sockfd[i]);
+
+       exit(0);
+}
+
+int create_ac_socket(unsigned int ac) 
+{
+       struct sockaddr_in my_addr;
+       int sockfd;
+       unsigned int yes=1, tos;
+
+
+       if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
+       {
+               perror("Socket nelze otevrit");
+               return -1;
+       }
+       
+       if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
+               perror("Chyba v nastaveni soketu");
+               return -1;
+       }
+
+       if (opt_same_interface) {
+               int receive = 1;
+               if (setsockopt(sockfd, SOL_IP, IP_PKTINFO, &receive, sizeof(receive)) == -1) {
+                       perror("setsockopt: IP_PKTINFO");
+                       exit(1);
+               }
+       }
+
+
+   //  bzero(&my_addr, sizeof(my_addr));
+       memset(&my_addr,0, sizeof(my_addr));
+       my_addr.sin_family = AF_INET;
+       my_addr.sin_addr.s_addr = INADDR_ANY;
+       my_addr.sin_port = htons(BASE_PORT + ac);
+       
+       if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1) {
+               perror("Chyba v bind");
+               close(sockfd);
+               return -1;
+       }
+       
+       //tos = ((AC_NUM - ac) *2 - 1)*32;
+       tos = ac_to_tos[ac];
+       if (setsockopt(sockfd, SOL_IP, IP_TOS, &tos, sizeof(tos))) {
+               perror("Unable to set TOS");
+               close(sockfd);
+               return -1;
+       }
+
+       return sockfd;
+}
+
+void* qhandler(void* queue)
+{
+       union msg_buff buff;
+       struct  sockaddr_in rem_addr;
+       int     mlen;
+       unsigned int rem_addr_length;
+       intptr_t ac;
+       char cbufrec[512], cbufsend[512];
+       struct iovec  iov;
+       struct msghdr msg;
+       struct in_pktinfo *ipi = NULL;
+       struct timespec ts;
+       
+       ac = (intptr_t) queue;
+        rem_addr_length=sizeof(rem_addr);
+
+       block_signals();
+       set_rt_prio(90-ac);
+
+       while (1) {
+               struct cmsghdr *cmsg;
+
+               iov.iov_base = &buff;
+               iov.iov_len = sizeof(buff);
+               msg.msg_name = (void*)&rem_addr;
+               msg.msg_namelen = sizeof(rem_addr);
+               msg.msg_iov = &iov;
+               msg.msg_iovlen = 1;
+               msg.msg_flags = 0;
+               msg.msg_control = cbufrec;
+               msg.msg_controllen = sizeof(cbufrec);
+
+               while ((mlen = recvmsg(ac_sockfd[ac], &msg, 0)) < 0) {
+                       if (errno == EINTR) continue;
+                       perror("recvmsg");
+                       return NULL;
+               }
+               clock_gettime(CLOCK_REALTIME, &ts);
+               buff.msg.sendback_timestamp = ts.tv_sec*1000000000 + ts.tv_nsec;
+
+
+               if (opt_same_interface) {
+                       /* determine receiving interface */
+                       for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+                               if (cmsg->cmsg_level == SOL_IP) {
+                                       if (cmsg->cmsg_type == IP_PKTINFO) {
+/*                                             char spec_dst[20], addr[20]; */
+                                               ipi = (struct in_pktinfo*)CMSG_DATA(cmsg);
+                                               if (cmsg->cmsg_len <= sizeof(cbufsend)) {
+                                                       struct in_pktinfo *ipi2;
+                                                       msg.msg_control = cbufsend;
+                                                       msg.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
+                                                       cmsg = CMSG_FIRSTHDR(&msg);
+                                                       cmsg->cmsg_level = SOL_IP;
+                                                       cmsg->cmsg_type = IP_PKTINFO;
+                                                       cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+                                                       /* Initialize the payload: */
+                                                       ipi2 = (struct in_pktinfo*)CMSG_DATA(cmsg);
+                                                       memset(ipi2, 0, sizeof(*ipi2));
+                                                       ipi2->ipi_ifindex = ipi->ipi_ifindex;
+
+                                               } else {
+                                                       fprintf(stderr, "cbufsend too small\n");
+                                                       msg.msg_control = NULL;
+                                                       msg.msg_controllen = 0;
+                                               }
+/*                                             strncpy(spec_dst, inet_ntoa(ipi->ipi_spec_dst), sizeof(spec_dst)-1); */
+/*                                             strncpy(addr,     inet_ntoa(ipi->ipi_addr),     sizeof(addr)-1); */
+/*                                             printf("pktinfo if=%d %s %s\n", ipi->ipi_ifindex, spec_dst, addr); */
+                                       }
+                               }
+                       }
+               } else {
+                       msg.msg_control = NULL;
+                       msg.msg_controllen = 0;
+               }
+#ifdef DEBUG
+               printf("%d",ac);
+               fflush(stdout);
+#endif
+               receivers[ac].received++;
+               msg.msg_iov->iov_len = mlen;
+#ifdef WITH_FWP
+               /* resp_port is already stored in network order */
+               rem_addr.sin_port = buff.msg.resp_port;
+#endif
+               while (sendmsg(ac_sockfd[ac], &msg, 0) < 0) {
+                           if (errno == EINTR) continue;
+                           perror("sendmsg");
+                           return NULL;
+               }
+       }
+}
+
+
+int main(int argc, char *argv[])
+{
+       int rc;
+       intptr_t ac;
+       pthread_attr_t attr;
+       pthread_t thread;
+
+       char opt;
+
+
+       while ((opt = getopt(argc, argv, "I")) != -1) {
+               switch (opt) {
+                       case 'I':
+                               opt_same_interface = true;
+                               break;
+                       default:
+                               fprintf(stderr, "Usage: %s [ options ]\n\n", argv[0]);
+                               fprintf(stderr, "Options:\n");
+                               fprintf(stderr, "    -I  send back through the same interface (bypass routing tables)\n");
+                               exit(1);
+               }
+       }
+       pthread_attr_init(&attr);
+
+       if (signal(SIGTERM, stopper) == SIG_ERR) {
+               perror("Signal handler registration error");
+               exit(1);
+       }
+               
+       if (signal(SIGINT, stopper) == SIG_ERR) {
+               perror("Signal handler registration error");
+               exit(1);
+       }
+
+       for (ac = 0; ac < AC_NUM; ac++) {
+               ac_sockfd[ac] = create_ac_socket(ac);
+               rc = pthread_create(&thread, &attr, qhandler, (void*) ac); 
+
+       }
+       
+       while (1) {
+               printf("\r");
+               for (ac = 0; ac < AC_NUM; ac++) {
+                       int delta = receivers[ac].received - receivers[ac].last_received;
+                       receivers[ac].last_received = receivers[ac].received;
+                       fprintf(stderr, "%s %5d %4d/s ", ac_to_text[ac], receivers[ac].received, delta);
+               }
+               fflush(stdout);
+               sleep(1);
+       }
+       printf("\n");
+
+       return 0;
+
+}
diff --git a/src/update-frescor-svn b/src/update-frescor-svn
new file mode 100755 (executable)
index 0000000..bb2167f
--- /dev/null
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# Script to track FRESCOR SVN repositories. We do this in order not to
+# diverge to much from the original code so that it can be easily
+# joined in future if it will be necessary.
+
+set -e
+
+update() {
+    local dir=$1
+    local svnrepo=$2
+    cd $dir
+    echo "Updating $dir"
+    if ! git config --get  svn-remote.svn.url > /dev/null; then
+       git svn init $svnrepo
+    fi
+
+    git svn fetch
+    local gitbranch=`git show-ref --verify --hash refs/heads/frescor-svn`
+    local svnbranch=`git show-ref --verify --hash refs/remotes/git-svn`
+    
+    if [ -z "$gitbranch" ]; then
+       echo "  Creating frescor-svn branch"
+       git branch frescor-svn git-svn
+    else
+       if [ "$gitbranch" != "$svnbranch" ]; then
+           echo "  Merging SVN to branch frescor-svn"
+           git merge git-svn
+           git checkout master
+       else
+           echo "  Already up-to-date"
+       fi
+    fi
+    cd ..
+}
+
+update frsh-include http://www.frescor.org/private/svn/frescor/frsh/trunk/include
+update fosa        http://www.frescor.org/private/svn/frescor/fosa/trunk
+update fna         http://www.frescor.org/private/svn/frescor/fna/trunk
diff --git a/src/update-to-git-head b/src/update-to-git-head
new file mode 100755 (executable)
index 0000000..e19452b
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+find -type d -name .git -print \
+       -execdir git checkout master \; \
+       -execdir git pull \;
diff --git a/src/wvtest.sh b/src/wvtest.sh
new file mode 100755 (executable)
index 0000000..30574cb
--- /dev/null
@@ -0,0 +1,154 @@
+#
+# Include this file in your shell script by using:
+#         #!/bin/sh
+#         . ./wvtest.sh
+#
+
+# we don't quote $TEXT in case it contains newlines; newlines
+# aren't allowed in test output.  However, we set -f so that
+# at least shell glob characters aren't processed.
+_wvtextclean()
+{
+       ( set -f; echo $* )
+}
+
+
+if [ -n "$BASH_VERSION" ]; then
+       _wvfind_caller()
+       {
+               LVL=$1
+               WVCALLER_FILE=${BASH_SOURCE[2]}
+               WVCALLER_LINE=${BASH_LINENO[1]}
+       }
+else
+       _wvfind_caller()
+       {
+               LVL=$1
+               WVCALLER_FILE="unknown"
+               WVCALLER_LINE=0
+       }
+fi
+
+
+_wvcheck()
+{
+       CODE="$1"
+       TEXT=$(_wvtextclean "$2")
+       OK=ok
+       if [ "$CODE" -ne 0 ]; then
+               OK=FAILED
+       fi
+       echo "! $WVCALLER_FILE:$WVCALLER_LINE  $TEXT  $OK" >&2
+       if [ "$CODE" -ne 0 ]; then
+               exit $CODE
+       else
+               return 0
+       fi
+}
+
+
+WVPASS()
+{
+       TEXT="$*"
+       
+       _wvfind_caller
+       if "$@"; then
+               _wvcheck 0 "$TEXT"
+               return 0
+       else
+               _wvcheck 1 "$TEXT"
+               # NOTREACHED
+               return 1
+       fi
+}
+
+
+WVFAIL()
+{
+       TEXT="$*"
+       
+       _wvfind_caller
+       if "$@"; then
+               _wvcheck 1 "NOT($TEXT)"
+               # NOTREACHED
+               return 1
+       else
+               _wvcheck 0 "NOT($TEXT)"
+               return 0
+       fi
+}
+
+
+_wvgetrv()
+{
+       ( "$@" >&2 )
+       echo -n $?
+}
+
+
+WVPASSEQ()
+{
+       _wvfind_caller
+       _wvcheck $(_wvgetrv [ "$#" -eq 2 ]) "exactly 2 arguments"
+       echo "Comparing:" >&2
+       echo "$1" >&2
+       echo "--" >&2
+       echo "$2" >&2
+       _wvcheck $(_wvgetrv [ "$1" = "$2" ]) "'$1' = '$2'"
+}
+
+
+WVPASSNE()
+{
+       _wvfind_caller
+       _wvcheck $(_wvgetrv [ "$#" -eq 2 ]) "exactly 2 arguments"
+       echo "Comparing:" >&2
+       echo "$1" >&2
+       echo "--" >&2
+       echo "$2" >&2
+       _wvcheck $(_wvgetrv [ "$1" != "$2" ]) "'$1' != '$2'"
+}
+
+
+WVPASSRC()
+{
+       RC=$?
+       _wvfind_caller
+       _wvcheck $(_wvgetrv [ $RC -eq 0 ]) "return code($RC) == 0"
+}
+
+
+WVFAILRC()
+{
+       RC=$?
+       _wvfind_caller
+       _wvcheck $(_wvgetrv [ $RC -ne 0 ]) "return code($RC) != 0"
+}
+
+
+WVSTART()
+{
+       echo >&2
+       _wvfind_caller
+       echo "Testing \"$*\" in $WVCALLER_FILE:" >&2
+}
+
+
+root=$(
+old_pwd=""
+while [ ! -e Makefile.rules ]; do
+       if [ "$old_pwd" = `pwd`  ]; then 
+              echo "Makefile.rules has not been found in this or parent directory" >&2; exit 1; 
+       else
+              old_pwd=`pwd`; 
+              cd -L .. 2>/dev/null; 
+       fi; 
+done; 
+pwd
+)
+
+if [ "$root" ]; then
+    PATH="$root/_compiled/bin:$root/_compiled/bin-tests:$PATH"
+else
+    exit 1
+fi