From aff0b849641d101fc4d489f06af77a82724e61bb Mon Sep 17 00:00:00 2001 From: gauthier <gauthier@mycompany.com> Date: Mon, 27 Jul 2015 15:14:25 +0000 Subject: [PATCH] moved RAL-LTE from trunk/openair3 to extras/openair3 git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7752 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair3/RAL-LTE/COPYING | 674 ---- openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C.c | 42 - ...ata_types_for_information_elements_codec.c | 34 - .../C/MIH_C_F1_basic_data_types_codec.c | 392 --- .../C/MIH_C_F2_general_data_types_codec.c | 80 - .../C/MIH_C_F3_data_types_for_address_codec.c | 202 -- .../C/MIH_C_F4_data_types_for_links_codec.c | 1351 -------- .../C/MIH_C_F9_data_types_for_qos_codec.c | 274 -- .../C/MIH_C_L2_type_values_for_tlv_encoding.c | 356 -- .../C/MIH_C_Medieval_extensions.c | 671 ---- .../INTERFACE-802.21/C/MIH_C_bit_buffer.c | 528 --- .../INTERFACE-802.21/C/MIH_C_header_codec.c | 163 - .../RAL-LTE/INTERFACE-802.21/C/MIH_C_log.c | 190 - .../INTERFACE-802.21/C/MIH_C_msg_codec.c | 1201 ------- .../C/MIH_C_primitive_codec.c | 892 ----- .../RAL-LTE/INTERFACE-802.21/DOXYGEN/Doxyfile | 1554 --------- .../INTERFACE-802.21/DOXYGEN/footer.html | 16 - .../RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C.h | 63 - ...ata_types_for_information_elements_codec.h | 75 - .../INCLUDE/MIH_C_F1_basic_data_types_codec.h | 133 - .../MIH_C_F2_general_data_types_codec.h | 77 - .../MIH_C_F3_data_types_for_address_codec.h | 83 - .../MIH_C_F4_data_types_for_links_codec.h | 137 - .../MIH_C_F9_data_types_for_qos_codec.h | 98 - .../MIH_C_L2_type_values_for_tlv_encoding.h | 76 - .../INCLUDE/MIH_C_Link_Constants.h | 110 - .../INCLUDE/MIH_C_Link_Messages.h | 315 -- .../INCLUDE/MIH_C_Link_Primitives.h | 231 -- .../INCLUDE/MIH_C_Medieval_extensions.h | 104 - .../INTERFACE-802.21/INCLUDE/MIH_C_Types.h | 3070 ----------------- .../INCLUDE/MIH_C_bit_buffer.h | 151 - .../INCLUDE/MIH_C_header_codec.h | 121 - .../INTERFACE-802.21/INCLUDE/MIH_C_log.h | 128 - .../INCLUDE/MIH_C_msg_codec.h | 167 - .../INCLUDE/MIH_C_primitive_codec.h | 115 - openair3/RAL-LTE/INTERFACE-802.21/Makefile | 68 - openair3/RAL-LTE/INTERFACE-802.21/readme.txt | 14 - .../RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb.h | 48 - .../LTE_RAL_ENB/INCLUDE/lteRALenb_action.h | 118 - .../LTE_RAL_ENB/INCLUDE/lteRALenb_constants.h | 58 - .../LTE_RAL_ENB/INCLUDE/lteRALenb_main.h | 218 -- .../LTE_RAL_ENB/INCLUDE/lteRALenb_mih_msg.h | 202 -- .../INCLUDE/lteRALenb_parameters.h | 78 - .../LTE_RAL_ENB/INCLUDE/lteRALenb_process.h | 76 - .../LTE_RAL_ENB/INCLUDE/lteRALenb_proto.h | 82 - .../LTE_RAL_ENB/INCLUDE/lteRALenb_rrc_msg.h | 69 - .../LTE_RAL_ENB/INCLUDE/lteRALenb_subscribe.h | 80 - .../INCLUDE/lteRALenb_thresholds.h | 82 - .../LTE_RAL_ENB/INCLUDE/lteRALenb_variables.h | 166 - .../RAL-LTE/LTE_RAL_ENB/INCLUDE/rrc_d_types.h | 38 - .../MIH-USER/dist/eNB_lte_user.conf | 40 - .../LTE_RAL_ENB/MIH-USER/dist/link_sap.conf | 47 - .../LTE_RAL_ENB/MIH-USER/dist/odtone.conf | 71 - .../MIH-USER/lte_test_user/Jamfile | 33 - .../MIH-USER/lte_test_user/dummy_130606.tgz | Bin 108774 -> 0 bytes .../MIH-USER/lte_test_user/eNB_lte_user.conf | 40 - .../MIH-USER/lte_test_user/rg_mih_usr.cpp | 1358 -------- openair3/RAL-LTE/LTE_RAL_ENB/Makefile | 69 - .../LTE_RAL_ENB/SRC/lteRALenb_action.c | 890 ----- .../RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_ioctl.c | 725 ---- .../RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_main.c | 340 -- .../LTE_RAL_ENB/SRC/lteRALenb_mih_msg.c | 1447 -------- .../LTE_RAL_ENB/SRC/lteRALenb_parameters.c | 182 - .../LTE_RAL_ENB/SRC/lteRALenb_process.c | 670 ---- .../LTE_RAL_ENB/SRC/lteRALenb_rrc_msg.c | 168 - .../LTE_RAL_ENB/SRC/lteRALenb_subscribe.c | 113 - .../LTE_RAL_ENB/SRC/lteRALenb_thresholds.c | 171 - .../RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue.h | 48 - .../LTE_RAL_UE/INCLUDE/lteRALue_action.h | 81 - .../LTE_RAL_UE/INCLUDE/lteRALue_constants.h | 60 - .../LTE_RAL_UE/INCLUDE/lteRALue_main.h | 187 - .../LTE_RAL_UE/INCLUDE/lteRALue_mih_execute.h | 80 - .../LTE_RAL_UE/INCLUDE/lteRALue_mih_msg.h | 153 - .../LTE_RAL_UE/INCLUDE/lteRALue_parameters.h | 78 - .../LTE_RAL_UE/INCLUDE/lteRALue_proto.h | 54 - .../LTE_RAL_UE/INCLUDE/lteRALue_rrc_msg.h | 69 - .../LTE_RAL_UE/INCLUDE/lteRALue_subscribe.h | 79 - .../LTE_RAL_UE/INCLUDE/lteRALue_thresholds.h | 83 - .../LTE_RAL_UE/INCLUDE/lteRALue_variables.h | 83 - .../RAL-LTE/LTE_RAL_UE/INCLUDE/nas_ue_ioctl.h | 65 - .../RAL-LTE/LTE_RAL_UE/INCLUDE/rrc_d_types.h | 45 - .../LTE_RAL_UE/MIH-USER/dist/link_sap.conf | 47 - .../LTE_RAL_UE/MIH-USER/dist/lte_user.conf | 40 - .../LTE_RAL_UE/MIH-USER/dist/odtone.conf | 71 - .../LTE_RAL_UE/MIH-USER/lte_test_user/Jamfile | 34 - .../MIH-USER/lte_test_user/README.txt | 11 - .../MIH-USER/lte_test_user/lte_user.conf | 42 - .../MIH-USER/lte_test_user/mih_usr.cpp | 1509 -------- .../MIH-USER/lte_test_user/ue_lte_user.conf | 42 - .../MIH-USER/lte_test_user/ue_lte_user.cpp | 1412 -------- openair3/RAL-LTE/LTE_RAL_UE/Makefile | 75 - .../RAL-LTE/LTE_RAL_UE/SRC/lteRALue_action.c | 240 -- .../RAL-LTE/LTE_RAL_UE/SRC/lteRALue_ioctl.c | 455 --- .../RAL-LTE/LTE_RAL_UE/SRC/lteRALue_main.c | 375 -- .../LTE_RAL_UE/SRC/lteRALue_mih_execute.c | 224 -- .../RAL-LTE/LTE_RAL_UE/SRC/lteRALue_mih_msg.c | 966 ------ .../LTE_RAL_UE/SRC/lteRALue_parameters.c | 145 - .../RAL-LTE/LTE_RAL_UE/SRC/lteRALue_process.c | 301 -- .../RAL-LTE/LTE_RAL_UE/SRC/lteRALue_rrc_msg.c | 283 -- .../LTE_RAL_UE/SRC/lteRALue_subscribe.c | 136 - .../LTE_RAL_UE/SRC/lteRALue_thresholds.c | 313 -- openair3/RAL-LTE/Makefile.inc | 43 - .../802.21-SCENARIO/VERSION0/README.txt | 12 - .../VERSION0/mih_mscgen_page_0.png | Bin 57361 -> 0 bytes .../VERSION0/mih_mscgen_page_1.png | Bin 52204 -> 0 bytes .../VERSION0/mih_mscgen_page_10.png | Bin 51804 -> 0 bytes .../VERSION0/mih_mscgen_page_11.png | Bin 51536 -> 0 bytes .../VERSION0/mih_mscgen_page_12.png | Bin 51622 -> 0 bytes .../VERSION0/mih_mscgen_page_2.png | Bin 55531 -> 0 bytes .../VERSION0/mih_mscgen_page_3.png | Bin 51880 -> 0 bytes .../VERSION0/mih_mscgen_page_4.png | Bin 54607 -> 0 bytes .../802.21-SCENARIO/VERSION0/mih_usr.cpp | 1457 -------- .../802.21-SCENARIO/VERSION0/rg_mih_usr.cpp | 1167 ------- .../RAL-DUMMY/802.21-SCENARIO/sendUDP-01 | Bin 12329 -> 0 bytes .../RAL-DUMMY/802.21-SCENARIO/sendUDP-FF | Bin 12329 -> 0 bytes .../RAL-DUMMY/INCLUDE/eRALlte_action.h | 63 - .../RAL-DUMMY/INCLUDE/eRALlte_constants.h | 81 - .../RAL-DUMMY/INCLUDE/eRALlte_mih_msg.h | 188 - .../RAL-DUMMY/INCLUDE/eRALlte_parameters.h | 62 - .../RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_proto.h | 90 - .../RAL-DUMMY/INCLUDE/eRALlte_subscribe.h | 64 - .../RAL-DUMMY/INCLUDE/eRALlte_thresholds.h | 64 - .../RAL-DUMMY/INCLUDE/eRALlte_variables.h | 239 -- .../RAL-DUMMY/INCLUDE/mRALlte_action.h | 74 - .../RAL-DUMMY/INCLUDE/mRALlte_constants.h | 57 - .../RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_get.h | 70 - .../RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_main.h | 80 - .../RAL-DUMMY/INCLUDE/mRALlte_mih_msg.h | 155 - .../RAL-DUMMY/INCLUDE/mRALlte_parameters.h | 73 - .../RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_proto.h | 48 - .../RAL-DUMMY/INCLUDE/mRALlte_subscribe.h | 74 - .../RAL-DUMMY/INCLUDE/mRALlte_thresholds.h | 74 - .../RAL-DUMMY/INCLUDE/mRALlte_variables.h | 134 - .../RAL-LTE/RAL-DUMMY/INCLUDE/nasUE_config.h | 109 - .../RAL-DUMMY/INCLUDE/nas_rg_netlink.h | 242 -- .../RAL-LTE/RAL-DUMMY/INCLUDE/nas_ue_ioctl.h | 70 - .../RAL-DUMMY/INCLUDE/nas_ue_netlink.h | 234 -- .../RAL-LTE/RAL-DUMMY/INCLUDE/rrc_d_types.h | 37 - .../RAL-LTE/RAL-DUMMY/MSCGEN_CHART/msc_gen.py | 344 -- openair3/RAL-LTE/RAL-DUMMY/Makefile | 91 - openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_NAS.c | 921 ----- .../RAL-LTE/RAL-DUMMY/SRC/eRALlte_action.c | 890 ----- openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_main.c | 532 --- .../RAL-LTE/RAL-DUMMY/SRC/eRALlte_mih_msg.c | 1945 ----------- .../RAL-DUMMY/SRC/eRALlte_parameters.c | 74 - .../RAL-LTE/RAL-DUMMY/SRC/eRALlte_process.c | 546 --- .../RAL-LTE/RAL-DUMMY/SRC/eRALlte_subscribe.c | 132 - .../RAL-DUMMY/SRC/eRALlte_thresholds.c | 75 - openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_NAS.c | 468 --- .../RAL-LTE/RAL-DUMMY/SRC/mRALlte_action.c | 229 -- openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_get.c | 56 - openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_main.c | 447 --- .../RAL-LTE/RAL-DUMMY/SRC/mRALlte_mih_msg.c | 1434 -------- .../RAL-DUMMY/SRC/mRALlte_parameters.c | 136 - .../RAL-LTE/RAL-DUMMY/SRC/mRALlte_process.c | 297 -- .../RAL-LTE/RAL-DUMMY/SRC/mRALlte_subscribe.c | 75 - .../RAL-DUMMY/SRC/mRALlte_thresholds.c | 219 -- openair3/RAL-LTE/RAL-DUMMY/SRC/nasRGdummy.c | 223 -- openair3/RAL-LTE/RAL-DUMMY/SRC/nasUEdummy.c | 464 --- openair3/RAL-LTE/RAL-LTE.readme.txt | 113 - 160 files changed, 44293 deletions(-) delete mode 100644 openair3/RAL-LTE/COPYING delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F13_data_types_for_information_elements_codec.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F1_basic_data_types_codec.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F2_general_data_types_codec.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F3_data_types_for_address_codec.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F4_data_types_for_links_codec.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F9_data_types_for_qos_codec.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_L2_type_values_for_tlv_encoding.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_Medieval_extensions.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_bit_buffer.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_header_codec.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_log.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_msg_codec.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_primitive_codec.c delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/DOXYGEN/Doxyfile delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/DOXYGEN/footer.html delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F13_data_types_for_information_elements_codec.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F1_basic_data_types_codec.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F2_general_data_types_codec.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F3_data_types_for_address_codec.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F4_data_types_for_links_codec.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F9_data_types_for_qos_codec.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_L2_type_values_for_tlv_encoding.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Constants.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Messages.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Primitives.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Medieval_extensions.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Types.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_bit_buffer.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_header_codec.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_log.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_msg_codec.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_primitive_codec.h delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/Makefile delete mode 100755 openair3/RAL-LTE/INTERFACE-802.21/readme.txt delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_action.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_constants.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_main.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_mih_msg.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_parameters.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_process.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_proto.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_rrc_msg.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_subscribe.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_thresholds.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_variables.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/rrc_d_types.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/eNB_lte_user.conf delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/link_sap.conf delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/odtone.conf delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/Jamfile delete mode 100644 openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/dummy_130606.tgz delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/eNB_lte_user.conf delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/rg_mih_usr.cpp delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/Makefile delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_action.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_ioctl.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_main.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_mih_msg.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_parameters.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_process.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_rrc_msg.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_subscribe.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_thresholds.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_action.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_constants.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_main.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_mih_execute.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_mih_msg.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_parameters.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_proto.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_rrc_msg.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_subscribe.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_thresholds.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_variables.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/nas_ue_ioctl.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/rrc_d_types.h delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/link_sap.conf delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/lte_user.conf delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/odtone.conf delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/Jamfile delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/README.txt delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/lte_user.conf delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/mih_usr.cpp delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.conf delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.cpp delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/Makefile delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_action.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_ioctl.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_main.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_mih_execute.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_mih_msg.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_parameters.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_process.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_rrc_msg.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_subscribe.c delete mode 100755 openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_thresholds.c delete mode 100755 openair3/RAL-LTE/Makefile.inc delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/README.txt delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_0.png delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_1.png delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_10.png delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_11.png delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_12.png delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_2.png delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_3.png delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_4.png delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_usr.cpp delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/rg_mih_usr.cpp delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/sendUDP-01 delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/sendUDP-FF delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_action.h delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_constants.h delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_mih_msg.h delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_parameters.h delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_proto.h delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_subscribe.h delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_thresholds.h delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_variables.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_action.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_constants.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_get.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_main.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_mih_msg.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_parameters.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_proto.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_subscribe.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_thresholds.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_variables.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nasUE_config.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_rg_netlink.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_ue_ioctl.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_ue_netlink.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/INCLUDE/rrc_d_types.h delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/MSCGEN_CHART/msc_gen.py delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/Makefile delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_NAS.c delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_action.c delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_main.c delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_mih_msg.c delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_parameters.c delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_process.c delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_subscribe.c delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_thresholds.c delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_NAS.c delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_action.c delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_get.c delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_main.c delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_mih_msg.c delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_parameters.c delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_process.c delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_subscribe.c delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_thresholds.c delete mode 100644 openair3/RAL-LTE/RAL-DUMMY/SRC/nasRGdummy.c delete mode 100755 openair3/RAL-LTE/RAL-DUMMY/SRC/nasUEdummy.c delete mode 100644 openair3/RAL-LTE/RAL-LTE.readme.txt diff --git a/openair3/RAL-LTE/COPYING b/openair3/RAL-LTE/COPYING deleted file mode 100644 index 94a9ed024d..0000000000 --- a/openair3/RAL-LTE/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. 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 -them 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 prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. 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. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey 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; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If 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 convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU 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 that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - 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. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -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. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can 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/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -<http://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C.c deleted file mode 100755 index 6be73f0864..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C.c +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_C -#include "MIH_C.h" -//----------------------------------------------------------------------------- -void MIH_C_init(void) -{ - //----------------------------------------------------------------------------- -} -//----------------------------------------------------------------------------- -void MIH_C_exit(void) -{ - //----------------------------------------------------------------------------- -} diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F13_data_types_for_information_elements_codec.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F13_data_types_for_information_elements_codec.c deleted file mode 100755 index e43a7e98a6..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F13_data_types_for_information_elements_codec.c +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS_C -#include "MIH_C_F13_data_types_for_information_elements_codec.h" - - diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F1_basic_data_types_codec.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F1_basic_data_types_codec.c deleted file mode 100755 index 4987733e25..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F1_basic_data_types_codec.c +++ /dev/null @@ -1,392 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_F1_BASIC_DATA_TYPES_CODEC_C -#include "MIH_C_F1_basic_data_types_codec.h" -#include <inttypes.h> - -//----------------------------------------------------------------------------- -unsigned int MIH_C_BITMAP82String(MIH_C_BITMAP8_T* dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - return sprintf(bufP, "0x%02X", *dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP8_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP8_T* dataP) -{ - printf("[MIH_C] %s: %02X\n", __FUNCTION__, *dataP); - BitBuffer_write8(bbP, *dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP16_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP16_T* dataP) -{ - printf("[MIH_C] %s: %04X\n", __FUNCTION__, *dataP); - BitBuffer_write16(bbP, *dataP); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_BITMAP162String(MIH_C_BITMAP16_T* dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - return sprintf(bufP, "0x%04X", *dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP24_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP24_T* dataP) -{ - //----------------------------------------------------------------------------- - printf("[MIH_C] %s: %02X%02X%02X\n", __FUNCTION__, dataP->val[0],dataP->val[1], dataP->val[2]); - MIH_C_BITMAP8_encode(bbP, &dataP->val[0]); - MIH_C_BITMAP8_encode(bbP, &dataP->val[1]); - MIH_C_BITMAP8_encode(bbP, &dataP->val[2]); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_BITMAP242String(MIH_C_BITMAP24_T* dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - return sprintf(bufP, "0x%02X%02X%02X", dataP->val[0], dataP->val[1], dataP->val[2]); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP32_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP32_T* dataP) -{ - printf("[MIH_C] %s: %08X\n", __FUNCTION__, *dataP); - BitBuffer_write32(bbP, *dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP64_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP64_T* dataP) -{ - //----------------------------------------------------------------------------- - printf("[MIH_C] %s: %16"PRIX64"\n", __FUNCTION__, *dataP); - BitBuffer_write32(bbP, (MIH_C_UNSIGNED_INT4_T)(*dataP>>32)); - BitBuffer_write32(bbP, (MIH_C_UNSIGNED_INT4_T)*dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP128_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP128_T* dataP) -{ - //----------------------------------------------------------------------------- - printf("[MIH_C] %s: %16"PRIX64"%16"PRIX64"\n", __FUNCTION__, dataP->val[0], dataP->val[1]); - MIH_C_BITMAP64_encode(bbP, &dataP->val[0]); - MIH_C_BITMAP64_encode(bbP, &dataP->val[1]); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP256_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP256_T* dataP) -{ - //----------------------------------------------------------------------------- - printf("[MIH_C] %s: %16"PRIX64"%16"PRIX64"%16"PRIX64"%16"PRIX64"\n", __FUNCTION__, dataP->val[0], dataP->val[1], dataP->val[2], dataP->val[3]); - MIH_C_BITMAP64_encode(bbP, &dataP->val[0]); - MIH_C_BITMAP64_encode(bbP, &dataP->val[1]); - MIH_C_BITMAP64_encode(bbP, &dataP->val[2]); - MIH_C_BITMAP64_encode(bbP, &dataP->val[3]); -} -//----------------------------------------------------------------------------- -void MIH_C_CHOICE_encode(Bit_Buffer_t* bbP, MIH_C_CHOICE_T* dataP) -{ - //----------------------------------------------------------------------------- - BitBuffer_write8(bbP, *dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_INTEGER1_encode(Bit_Buffer_t* bbP, MIH_C_INTEGER1_T* dataP) -{ - //----------------------------------------------------------------------------- - BitBuffer_write8(bbP, *dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_INTEGER2_encode(Bit_Buffer_t* bbP, MIH_C_INTEGER2_T* dataP) -{ - //----------------------------------------------------------------------------- - BitBuffer_write16(bbP, *dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_INTEGER4_encode(Bit_Buffer_t* bbP, MIH_C_INTEGER4_T* dataP) -{ - //----------------------------------------------------------------------------- - BitBuffer_write32(bbP, *dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_INTEGER8_encode(Bit_Buffer_t* bbP, MIH_C_INTEGER8_T* dataP) -{ - //----------------------------------------------------------------------------- - BitBuffer_write32(bbP, (MIH_C_UNSIGNED_INT4_T)(*dataP>>32)); - BitBuffer_write32(bbP, (MIH_C_UNSIGNED_INT4_T)*dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_NULL_encode(Bit_Buffer_t* bbP, MIH_C_NULL_T* dataP) -{ - ; -} -//----------------------------------------------------------------------------- -void MIH_C_OCTET_encode(Bit_Buffer_t* bbP, MIH_C_F1_Generic_Octet_t *dataP, int lengthP) -{ - //----------------------------------------------------------------------------- - BitBuffer_writeMem(bbP, dataP->val, lengthP); -} -//----------------------------------------------------------------------------- -void MIH_C_UNSIGNED_INT1_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT1_T* dataP) -{ - printf("[MIH_C] %s: %02X\n", __FUNCTION__, *dataP); - BitBuffer_write8(bbP, *dataP); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_UNSIGNED_INT12String(MIH_C_UNSIGNED_INT1_T* dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - return sprintf(bufP, "0x%02X", *dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_UNSIGNED_INT2_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT2_T* dataP) -{ - //----------------------------------------------------------------------------- - BitBuffer_write16(bbP, *dataP); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_UNSIGNED_INT22String(MIH_C_UNSIGNED_INT2_T* dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - return sprintf(bufP, "0x%04X", *dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_UNSIGNED_INT4_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT4_T* dataP) -{ - //----------------------------------------------------------------------------- - BitBuffer_write32(bbP, *dataP); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_UNSIGNED_INT42String(MIH_C_UNSIGNED_INT4_T* dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - return sprintf(bufP, "0x%08X", *dataP); -} -//----------------------------------------------------------------------------- -void MIH_C_UNSIGNED_INT8_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT8_T* dataP) -{ - //----------------------------------------------------------------------------- - BitBuffer_write32(bbP, (MIH_C_UNSIGNED_INT4_T)(*dataP>>32)); - BitBuffer_write32(bbP, (MIH_C_UNSIGNED_INT4_T)*dataP); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_UNSIGNED_INT82String(MIH_C_UNSIGNED_INT8_T* dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index = sprintf(bufP, "0x%08x", (MIH_C_UNSIGNED_INT4_T)(*dataP>>32)); - buffer_index = sprintf(&bufP[buffer_index], "%08x", (MIH_C_UNSIGNED_INT4_T)(*dataP)); - return buffer_index; - \ -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP8_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP8_T* dataP) -{ - *dataP = BitBuffer_read(bbP, 8); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP16_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP16_T* dataP) -{ - *dataP = BitBuffer_read(bbP, 16); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP24_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP24_T* dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_BITMAP8_decode(bbP, &dataP->val[0]); - MIH_C_BITMAP8_decode(bbP, &dataP->val[1]); - MIH_C_BITMAP8_decode(bbP, &dataP->val[2]); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP32_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP32_T* dataP) -{ - *dataP = BitBuffer_read(bbP, 32); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP64_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP64_T* dataP) -{ - //----------------------------------------------------------------------------- - *dataP = BitBuffer_read(bbP, 32); - *dataP = *dataP << 32; - *dataP = *dataP | BitBuffer_read(bbP, 32); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP128_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP128_T* dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_BITMAP64_decode(bbP, &dataP->val[0]); - MIH_C_BITMAP64_decode(bbP, &dataP->val[1]); -} -//----------------------------------------------------------------------------- -void MIH_C_BITMAP256_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP256_T* dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_BITMAP64_decode(bbP, &dataP->val[0]); - MIH_C_BITMAP64_decode(bbP, &dataP->val[1]); - MIH_C_BITMAP64_decode(bbP, &dataP->val[2]); - MIH_C_BITMAP64_decode(bbP, &dataP->val[3]); -} -//----------------------------------------------------------------------------- -void MIH_C_CHOICE_decode(Bit_Buffer_t* bbP, MIH_C_CHOICE_T* dataP) -{ - *dataP = BitBuffer_read(bbP, sizeof(MIH_C_CHOICE_T)*8); -} -//----------------------------------------------------------------------------- -void MIH_C_INTEGER1_decode(Bit_Buffer_t* bbP, MIH_C_INTEGER1_T* dataP) -{ - *dataP = BitBuffer_read(bbP, sizeof(MIH_C_INTEGER1_T)*8); -} -//----------------------------------------------------------------------------- -void MIH_C_INTEGER2_decode(Bit_Buffer_t* bbP, MIH_C_INTEGER2_T* dataP) -{ - *dataP = BitBuffer_read(bbP, sizeof(MIH_C_INTEGER2_T)*8); -} -//----------------------------------------------------------------------------- -void MIH_C_INTEGER4_decode(Bit_Buffer_t* bbP, MIH_C_INTEGER4_T* dataP) -{ - *dataP = BitBuffer_read(bbP, sizeof(MIH_C_INTEGER4_T)*8); -} -//----------------------------------------------------------------------------- -void MIH_C_INTEGER8_decode(Bit_Buffer_t* bbP, MIH_C_INTEGER8_T* dataP) -{ - //----------------------------------------------------------------------------- - *dataP = BitBuffer_read(bbP, sizeof(MIH_C_INTEGER4_T)*8); - *dataP = *dataP << (sizeof(MIH_C_INTEGER4_T)*8); - *dataP = *dataP | BitBuffer_read(bbP, sizeof(MIH_C_INTEGER4_T)*8); -} -//----------------------------------------------------------------------------- -void MIH_C_NULL_decode(Bit_Buffer_t* bbP) -{ - ; -} -//----------------------------------------------------------------------------- -void MIH_C_OCTET_decode(Bit_Buffer_t* bbP, MIH_C_F1_Generic_Octet_t *dataP, int lengthP) -{ - //----------------------------------------------------------------------------- - BitBuffer_readMem(bbP, dataP->val, lengthP); -} -//----------------------------------------------------------------------------- -void MIH_C_UNSIGNED_INT1_decode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT1_T* dataP) -{ - *dataP = BitBuffer_read(bbP, sizeof(MIH_C_UNSIGNED_INT1_T)*8); -} -//----------------------------------------------------------------------------- -void MIH_C_UNSIGNED_INT2_decode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT2_T* dataP) -{ - *dataP = BitBuffer_read(bbP, sizeof(MIH_C_UNSIGNED_INT2_T)*8); -} -//----------------------------------------------------------------------------- -void MIH_C_UNSIGNED_INT4_decode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT4_T* dataP) -{ - *dataP = BitBuffer_read(bbP, sizeof(MIH_C_UNSIGNED_INT4_T)*8); -} -//----------------------------------------------------------------------------- -void MIH_C_UNSIGNED_INT8_decode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT8_T* dataP) -{ - //----------------------------------------------------------------------------- - *dataP = BitBuffer_read(bbP, sizeof(MIH_C_UNSIGNED_INT4_T)*8); - *dataP = *dataP << 32; - *dataP = *dataP | BitBuffer_read(bbP, sizeof(MIH_C_UNSIGNED_INT4_T)*8); -} -//----------------------------------------------------------------------------- -void MIH_C_LIST_LENGTH_encode(Bit_Buffer_t* bbP, u_int16_t lengthP) -{ - //----------------------------------------------------------------------------- - unsigned int num_more_bytes; - int length; - - if (lengthP <= 128) { -#ifdef DEBUG_TRACE_DETAILS - printf("[MIH_C] %s: Length %02X\n", __FUNCTION__, lengthP); -#endif - BitBuffer_write8(bbP, (MIH_C_UNSIGNED_INT1_T)lengthP); - } else { - num_more_bytes = (lengthP - 128) / 255; - - if (((lengthP - 128) % 255) != 0) { - num_more_bytes += 1; - } - - printf("[MIH_C] %s: Length %02X on %d more bytes\n", __FUNCTION__, lengthP, num_more_bytes); - BitBuffer_write8(bbP, (MIH_C_UNSIGNED_INT1_T)(128 + num_more_bytes)); - length = lengthP - 128; - - while (length > 0) { - if (length >= 255) { - BitBuffer_write8(bbP, (MIH_C_UNSIGNED_INT1_T)(255)); - length = length - 255; - } else { - BitBuffer_write8(bbP, (MIH_C_UNSIGNED_INT1_T)(length)); - length = 0; - } - } - } -} -//----------------------------------------------------------------------------- -u_int16_t MIH_C_LIST_LENGTH_get_encode_num_bytes(u_int16_t lengthP) -{ - //----------------------------------------------------------------------------- - unsigned int num_more_bytes; - - if (lengthP <= 128) { - return sizeof (MIH_C_UNSIGNED_INT1_T); - } else { - num_more_bytes = (lengthP - 128) / 255; - - if (((lengthP - 128) % 255) != 0) { - num_more_bytes += 1; - } - - printf("[MIH_C] %s: Length %02X on %d more bytes\n", __FUNCTION__, lengthP, num_more_bytes); - return num_more_bytes + sizeof (MIH_C_UNSIGNED_INT1_T); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LIST_LENGTH_decode(Bit_Buffer_t* bbP, u_int16_t *lengthP) -{ - //----------------------------------------------------------------------------- - unsigned int num_more_bytes; - MIH_C_UNSIGNED_INT1_T byte1; - - byte1 = BitBuffer_read(bbP, sizeof(MIH_C_UNSIGNED_INT1_T)*8); - - if (byte1 >= 128) { - num_more_bytes = byte1 - 128; - *lengthP = 128; - - while (num_more_bytes > 0) { - *lengthP = *lengthP + BitBuffer_read(bbP, sizeof(MIH_C_UNSIGNED_INT1_T)*8); - num_more_bytes = num_more_bytes - 1; - } - -#ifdef DEBUG_TRACE_DETAILS - printf("[MIH_C] %s: Length %d \n", __FUNCTION__, *lengthP); -#endif - } else { - *lengthP = byte1; -#ifdef DEBUG_TRACE_DETAILS - printf("[MIH_C] %s: Length %d \n", __FUNCTION__, *lengthP); -#endif - } -} - - diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F2_general_data_types_codec.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F2_general_data_types_codec.c deleted file mode 100755 index b4b534f6e8..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F2_general_data_types_codec.c +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_F2_GENERAL_DATA_TYPES_CODEC_C -#include "MIH_C_F2_general_data_types_codec.h" -//----------------------------------------------------------------------------- -unsigned int MIH_C_BOOLEAN2String(MIH_C_BOOLEAN_T* dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - if (*dataP != MIH_C_BOOLEAN_FALSE) { - buffer_index += sprintf(&bufP[buffer_index], "TRUE"); - } else { - buffer_index += sprintf(&bufP[buffer_index], "FALSE"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_STATUS2String(MIH_C_STATUS_T *statusP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (*statusP) { - case MIH_C_STATUS_SUCCESS: - buffer_index += sprintf(&bufP[buffer_index], "STATUS_SUCCESS"); - break; - - case MIH_C_STATUS_UNSPECIFIED_FAILURE: - buffer_index += sprintf(&bufP[buffer_index], "STATUS_UNSPECIFIED_FAILURE"); - break; - - case MIH_C_STATUS_REJECTED: - buffer_index += sprintf(&bufP[buffer_index], "STATUS_REJECTED"); - break; - - case MIH_C_STATUS_AUTHORIZATION_FAILURE: - buffer_index += sprintf(&bufP[buffer_index], "STATUS_AUTHORIZATION_FAILURE"); - break; - - case MIH_C_STATUS_NETWORK_ERROR: - buffer_index += sprintf(&bufP[buffer_index], "STATUS_NETWORK_ERROR"); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "UNKNOWN_STATUS"); - } - - return buffer_index; -} - diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F3_data_types_for_address_codec.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F3_data_types_for_address_codec.c deleted file mode 100755 index 1af1b55592..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F3_data_types_for_address_codec.c +++ /dev/null @@ -1,202 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC_C -#include "MIH_C_F3_data_types_for_address_codec.h" - -//----------------------------------------------------------------------------- -unsigned int MIH_C_3GPP_2G_CELL_ID2String(MIH_C_3GPP_2G_CELL_ID_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "PLMN_ID = "); - buffer_index += MIH_C_PLMN_ID2String(&dataP->plmn_id, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "LAC = "); - buffer_index += MIH_C_LAC2String(&dataP->lac, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "CI = "); - buffer_index += MIH_C_CI2String(&dataP->ci, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_3GPP_2G_CELL_ID_encode(Bit_Buffer_t* bbP, MIH_C_3GPP_2G_CELL_ID_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_PLMN_ID_encode(bbP, &dataP->plmn_id); - MIH_C_LAC_encode(bbP, &dataP->lac); - MIH_C_CI_encode(bbP, &dataP->ci); -} -//----------------------------------------------------------------------------- -void MIH_C_3GPP_2G_CELL_ID_decode(Bit_Buffer_t* bbP, MIH_C_3GPP_2G_CELL_ID_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_PLMN_ID_decode(bbP, &dataP->plmn_id); - MIH_C_LAC_decode(bbP, &dataP->lac); - MIH_C_CI_decode(bbP, &dataP->ci); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_3GPP_3G_CELL_ID2String(MIH_C_3GPP_3G_CELL_ID_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += MIH_C_PLMN_ID2String(&dataP->plmn_id, &bufP[buffer_index]); - buffer_index += MIH_C_CELL_ID2String(&dataP->cell_id, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_3GPP_3G_CELL_ID_encode(Bit_Buffer_t* bbP, MIH_C_3GPP_3G_CELL_ID_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_PLMN_ID_encode(bbP, &dataP->plmn_id); - MIH_C_CELL_ID_encode(bbP, &dataP->cell_id); -} -//----------------------------------------------------------------------------- -void MIH_C_3GPP_3G_CELL_ID_decode(Bit_Buffer_t* bbP, MIH_C_3GPP_3G_CELL_ID_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_PLMN_ID_decode(bbP, &dataP->plmn_id); - MIH_C_CELL_ID_decode(bbP, &dataP->cell_id); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_ADDR2String(MIH_C_LINK_ADDR_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (dataP->choice) { - case MIH_C_CHOICE_MAC_ADDR: - buffer_index += sprintf(&bufP[buffer_index], "MAC_ADDR = "); - buffer_index += MIH_C_MAC_ADDR2String(&dataP->_union.mac_addr, &bufP[buffer_index]); - break; - - case MIH_C_CHOICE_3GPP_3G_CELL_ID: - buffer_index += sprintf(&bufP[buffer_index], "3GPP_3G_CELL_ID = "); - buffer_index = MIH_C_3GPP_3G_CELL_ID2String(&dataP->_union._3gpp_3g_cell_id, &bufP[buffer_index]); - break; - - case MIH_C_CHOICE_3GPP_2G_CELL_ID: - buffer_index += sprintf(&bufP[buffer_index], "3GPP_2G_CELL_ID = "); - buffer_index = MIH_C_3GPP_2G_CELL_ID2String(&dataP->_union._3gpp_2g_cell_id, &bufP[buffer_index]); - break; - - case MIH_C_CHOICE_3GPP_ADDR: - buffer_index += sprintf(&bufP[buffer_index], "3GPP_ADDR = "); - buffer_index = MIH_C_3GPP_ADDR2String(&dataP->_union._3gpp_addr, &bufP[buffer_index]); - break; - - case MIH_C_CHOICE_3GPP2_ADDR: - buffer_index += sprintf(&bufP[buffer_index], "3GPP2_ADDR = "); - buffer_index = MIH_C_3GPP2_ADDR2String(&dataP->_union._3gpp2_addr, &bufP[buffer_index]); - break; - - case MIH_C_CHOICE_OTHER_L2_ADDR: - buffer_index += sprintf(&bufP[buffer_index], "OTHER_L2_ADDR = "); - buffer_index = MIH_C_OTHER_L2_ADDR2String(&dataP->_union.other_l2_addr, &bufP[buffer_index]); - break; - - default: - buffer_index = sprintf(&bufP[buffer_index], "UNINITIALIZED ADDR"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_ADDR_encode(Bit_Buffer_t* bbP, MIH_C_LINK_ADDR_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case MIH_C_CHOICE_MAC_ADDR: - MIH_C_MAC_ADDR_encode(bbP, &dataP->_union.mac_addr); - break; - - case MIH_C_CHOICE_3GPP_3G_CELL_ID: - MIH_C_3GPP_3G_CELL_ID_encode(bbP, &dataP->_union._3gpp_3g_cell_id); - break; - - case MIH_C_CHOICE_3GPP_2G_CELL_ID: - MIH_C_3GPP_2G_CELL_ID_encode(bbP, &dataP->_union._3gpp_2g_cell_id); - break; - - case MIH_C_CHOICE_3GPP_ADDR: - MIH_C_3GPP_ADDR_encode(bbP, &dataP->_union._3gpp_addr); - break; - - case MIH_C_CHOICE_3GPP2_ADDR: - MIH_C_3GPP2_ADDR_encode(bbP, &dataP->_union._3gpp2_addr); - break; - - case MIH_C_CHOICE_OTHER_L2_ADDR: - MIH_C_OTHER_L2_ADDR_encode(bbP, &dataP->_union.other_l2_addr); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_LINK_ADDR_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_ADDR_decode(Bit_Buffer_t* bbP, MIH_C_LINK_ADDR_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case MIH_C_CHOICE_MAC_ADDR: - MIH_C_MAC_ADDR_decode(bbP, &dataP->_union.mac_addr); - break; - - case MIH_C_CHOICE_3GPP_3G_CELL_ID: - MIH_C_3GPP_3G_CELL_ID_decode(bbP, &dataP->_union._3gpp_3g_cell_id); - break; - - case MIH_C_CHOICE_3GPP_2G_CELL_ID: - MIH_C_3GPP_2G_CELL_ID_decode(bbP, &dataP->_union._3gpp_2g_cell_id); - break; - - case MIH_C_CHOICE_3GPP_ADDR: - MIH_C_3GPP_ADDR_decode(bbP, &dataP->_union._3gpp_addr); - break; - - case MIH_C_CHOICE_3GPP2_ADDR: - MIH_C_3GPP2_ADDR_decode(bbP, &dataP->_union._3gpp2_addr); - break; - - case MIH_C_CHOICE_OTHER_L2_ADDR: - MIH_C_OTHER_L2_ADDR_decode(bbP, &dataP->_union.other_l2_addr); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_LINK_ADDR_T %d\n", dataP->choice); - } -} - - - - diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F4_data_types_for_links_codec.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F4_data_types_for_links_codec.c deleted file mode 100755 index 4d63c244c8..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F4_data_types_for_links_codec.c +++ /dev/null @@ -1,1351 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC_C -#include "MIH_C_F4_data_types_for_links_codec.h" - - -#define MIH_C_OPMODE_NORMAL_MODE 0 -#define MIH_C_OPMODE_POWER_SAVING_MODE 1 -#define MIH_C_OPMODE_POWERED_DOWN 2 -//----------------------------------------------------------------------------- -unsigned int MIH_C_OPMODE2String2(MIH_C_OPMODE_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (*dataP) { - case MIH_C_OPMODE_NORMAL_MODE: - buffer_index+= sprintf(&bufP[buffer_index], "OPMODE_NORMAL_MODE"); - break; - - case MIH_C_OPMODE_POWER_SAVING_MODE: - buffer_index+= sprintf(&bufP[buffer_index], "POWER_SAVING_MODE"); - break; - - case MIH_C_OPMODE_POWERED_DOWN: - buffer_index+= sprintf(&bufP[buffer_index], "POWERED_DOWN"); - break; - - default: - buffer_index+= sprintf(&bufP[buffer_index], "UNKNOWN"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_DEV_STATE_RSP_encode(Bit_Buffer_t* bbP, MIH_C_DEV_STATE_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_DEVICE_INFO_encode(bbP, &dataP->_union.device_info); - break; - - case 1: - MIH_C_BATT_LEVEL_encode(bbP, &dataP->_union.batt_level); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_DEV_STATE_RSP_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_DEV_STATE_RSP_decode(Bit_Buffer_t* bbP, MIH_C_DEV_STATE_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_DEVICE_INFO_decode(bbP, &dataP->_union.device_info); - break; - - case 1: - MIH_C_BATT_LEVEL_decode(bbP, &dataP->_union.batt_level); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_DEV_STATE_RSP_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_EVENT_LIST2String2(MIH_C_LINK_EVENT_LIST_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - if (*dataP & MIH_C_BIT_LINK_DETECTED) buffer_index+= sprintf(&bufP[buffer_index], "LK_DETECTED,"); - - if (*dataP & MIH_C_BIT_LINK_UP) buffer_index+= sprintf(&bufP[buffer_index], "LK_UP,"); - - if (*dataP & MIH_C_BIT_LINK_DOWN) buffer_index+= sprintf(&bufP[buffer_index], "LK_DOWN,"); - - if (*dataP & MIH_C_BIT_LINK_PARAMETERS_REPORT) buffer_index+= sprintf(&bufP[buffer_index], "LK_PARAMETERS_REPORT,"); - - if (*dataP & MIH_C_BIT_LINK_GOING_DOWN) buffer_index+= sprintf(&bufP[buffer_index], "LK_GOING_DOWN,"); - - if (*dataP & MIH_C_BIT_LINK_HANDOVER_IMMINENT) buffer_index+= sprintf(&bufP[buffer_index], "LK_HANDOVER_IMMINENT,"); - - if (*dataP & MIH_C_BIT_LINK_HANDOVER_COMPLETE) buffer_index+= sprintf(&bufP[buffer_index], "LK_HANDOVER_COMPLETE,"); - - if (*dataP & MIH_C_BIT_LINK_PDU_TRANSMIT_STATUS) buffer_index+= sprintf(&bufP[buffer_index], "LK_PDU_TRANSMIT_STATUS"); - - if (*dataP == 0) buffer_index+= sprintf(&bufP[buffer_index], "NULL"); - - return buffer_index; -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_CMD_LIST2String2(MIH_C_LINK_CMD_LIST_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - if (*dataP & MIH_C_BIT_LINK_EVENT_SUBSCRIBE) buffer_index+= sprintf(&bufP[buffer_index], "LK_EVT_SUBSCRIBE,"); - - if (*dataP & MIH_C_BIT_LINK_EVENT_UNSUBSCRIBE) buffer_index+= sprintf(&bufP[buffer_index], "LK_EVT_UNSUBSCRIBE,"); - - if (*dataP & MIH_C_BIT_LINK_GET_PARAMETERS) buffer_index+= sprintf(&bufP[buffer_index], "LK_GET_PARAMETERS,"); - - if (*dataP & MIH_C_BIT_LINK_CONFIGURE_THRESHOLDS) buffer_index+= sprintf(&bufP[buffer_index], "LK_CONFIGURE_THRESHOLDS,"); - - if (*dataP & MIH_C_BIT_LINK_ACTION) buffer_index+= sprintf(&bufP[buffer_index], "LK_ACTION"); - - if (*dataP == 0) buffer_index+= sprintf(&bufP[buffer_index], "NULL"); - - return buffer_index; -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_TYPE2String2(MIH_C_LINK_TYPE_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (*dataP) { - case MIH_C_WIRELESS_GSM: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_GSM"); - break; - - case MIH_C_WIRELESS_GPRS: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_GPRS"); - break; - - case MIH_C_WIRELESS_EDGE: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_EDGE"); - break; - - case MIH_C_ETHERNET: - buffer_index += sprintf(&bufP[buffer_index], "ETHERNET"); - break; - - case MIH_C_WIRELESS_OTHER: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_OTHER"); - break; - - case MIH_C_WIRELESS_IEEE802_11: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_IEEE802_11"); - break; - - case MIH_C_WIRELESS_CDMA_2000: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_CDMA_2000"); - break; - - case MIH_C_WIRELESS_UMTS: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_UMTS"); - break; - - case MIH_C_WIRELESS_CDMA_2000_HRPD: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_CDMA_2000_HRPD"); - break; - - case MIH_C_WIRELESS_IEEE802_16: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_IEEE802_16"); - break; - - case MIH_C_WIRELESS_IEEE802_20: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_IEEE802_20"); - break; - - case MIH_C_WIRELESS_IEEE802_22: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_IEEE802_22"); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "WIRELESS_IEEE802_22"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_ID2String(MIH_C_LINK_ID_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - buffer_index += sprintf(&bufP[buffer_index], "LINK_TYPE = "); - buffer_index += MIH_C_LINK_TYPE2String2(&dataP->link_type, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], ", LINK_ADDR = "); - buffer_index += MIH_C_LINK_ADDR2String(&dataP->link_addr, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_ID_encode(Bit_Buffer_t* bbP, MIH_C_LINK_ID_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_TYPE_encode(bbP, &dataP->link_type); - MIH_C_LINK_ADDR_encode(bbP, &dataP->link_addr); -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_ID_decode(Bit_Buffer_t* bbP, MIH_C_LINK_ID_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_TYPE_decode(bbP, &dataP->link_type); - MIH_C_LINK_ADDR_decode(bbP, &dataP->link_addr); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_AC_ATTR2String2(MIH_C_LINK_AC_ATTR_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - if (*dataP & MIH_C_BIT_LINK_AC_ATTR_LINK_SCAN) buffer_index+= sprintf(&bufP[buffer_index], "AC_ATTR_LINK_SCAN"); - - if (*dataP & MIH_C_BIT_LINK_AC_ATTR_LINK_RES_RETAIN) buffer_index+= sprintf(&bufP[buffer_index], ",AC_ATTR_LINK_RES_RETAIN"); - - if (*dataP & MIH_C_BIT_LINK_AC_ATTR_DATA_FWD_REQ) buffer_index+= sprintf(&bufP[buffer_index], ",AC_ATTR_DATA_FWD_REQ"); - - if (*dataP == 0) buffer_index+= sprintf(&bufP[buffer_index], "NULL"); - - return buffer_index; -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_ACTION2String(MIH_C_LINK_ACTION_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - buffer_index += sprintf(&bufP[buffer_index], "LINK_AC_TYPE = "); - buffer_index += MIH_C_LINK_AC_TYPE2String2(&dataP->link_ac_type, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], ", LINK_AC_ATTR = "); - buffer_index += MIH_C_LINK_AC_ATTR2String2(&dataP->link_ac_attr, &bufP[buffer_index]); -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - buffer_index += sprintf(&bufP[buffer_index], ", LINK_AC_PARAM = "); - buffer_index += MIH_C_LINK_AC_PARAM2String(&dataP->link_ac_param, &bufP[buffer_index]); -#endif - return buffer_index; -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_AC_TYPE2String2(MIH_C_LINK_AC_TYPE_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (*dataP) { - case MIH_C_LINK_AC_TYPE_NONE: - buffer_index += sprintf(&bufP[buffer_index], "NONE"); - break; - - case MIH_C_LINK_AC_TYPE_LINK_DISCONNECT: - buffer_index += sprintf(&bufP[buffer_index], "LINK_DISCONNECT"); - break; - - case MIH_C_LINK_AC_TYPE_LINK_LOW_POWER: - buffer_index += sprintf(&bufP[buffer_index], "LINK_LOW_POWER"); - break; - - case MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN: - buffer_index += sprintf(&bufP[buffer_index], "POWER_DOWN"); - break; - - case MIH_C_LINK_AC_TYPE_LINK_POWER_UP: - buffer_index += sprintf(&bufP[buffer_index], "POWER_UP"); - break; -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - - case MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR: - buffer_index += sprintf(&bufP[buffer_index], "FLOW_ATTR"); - break; - - case MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES: - buffer_index += sprintf(&bufP[buffer_index], "ACTIVATE_RESOURCES"); - break; - - case MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES: - buffer_index += sprintf(&bufP[buffer_index], "DEACTIVATE_RESOURCES"); - break; -#endif - - default: - buffer_index += sprintf(&bufP[buffer_index], "UNKNOWN"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_ACTION_encode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_AC_TYPE_encode(bbP, &dataP->link_ac_type); - MIH_C_LINK_AC_ATTR_encode(bbP, &dataP->link_ac_attr); -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - MIH_C_LINK_AC_PARAM_encode(bbP, &dataP->link_ac_param); -#endif -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_ACTION_decode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_AC_TYPE_decode(bbP, &dataP->link_ac_type); - MIH_C_LINK_AC_ATTR_decode(bbP, &dataP->link_ac_attr); -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - MIH_C_LINK_AC_PARAM_decode(bbP, &dataP->link_ac_param); -#endif -} - -//----------------------------------------------------------------------------- -// MW Function to bypass ODTONE problem -void MIH_C_LINK_ACTION_short_decode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_AC_TYPE_decode(bbP, &dataP->link_ac_type); - MIH_C_LINK_AC_ATTR_decode(bbP, &dataP->link_ac_attr); - //#ifdef MIH_C_MEDIEVAL_EXTENSIONS - //MIH_C_LINK_AC_PARAM_decode(bbP, &dataP->link_ac_param); - //#endif -} - -//----------------------------------------------------------------------------- -void MIH_C_LINK_ACTION_REQ_encode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_REQ_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ID_encode(bbP, &dataP->link_id); - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - break; - - case 1: - MIH_C_LINK_ADDR_encode(bbP, &dataP->_union.link_addr); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_LINK_ACTION_REQ_T %d\n", dataP->choice); - } - - MIH_C_LINK_ACTION_encode(bbP, &dataP->link_action); - MIH_C_LINK_AC_EX_TIME_encode(bbP, &dataP->link_action_ex_time); -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_ACTION_REQ_decode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_REQ_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ID_decode(bbP, &dataP->link_id); - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - break; - - case 1: - MIH_C_LINK_ADDR_decode(bbP, &dataP->_union.link_addr); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_LINK_ACTION_REQ_T %d\n", dataP->choice); - } - - MIH_C_LINK_ACTION_decode(bbP, &dataP->link_action); - MIH_C_LINK_AC_EX_TIME_decode(bbP, &dataP->link_action_ex_time); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_SIG_STRENGTH2String(MIH_C_SIG_STRENGTH_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (dataP->choice) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "%d dBm",dataP->_union.dbm ); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "%d/100",dataP->_union.percentage ); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "UNINITIALIZED STRENGTH"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_SIG_STRENGTH_encode(Bit_Buffer_t* bbP, MIH_C_SIG_STRENGTH_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_INTEGER1_encode(bbP, &dataP->_union.dbm); - break; - - case 1: - MIH_C_PERCENTAGE_encode(bbP, &dataP->_union.percentage); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_SIG_STRENGTH_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_SIG_STRENGTH_decode(Bit_Buffer_t* bbP, MIH_C_SIG_STRENGTH_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_INTEGER1_decode(bbP, &dataP->_union.dbm); - break; - - case 1: - MIH_C_PERCENTAGE_decode(bbP, &dataP->_union.percentage); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_SIG_STRENGTH_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_SCAN_RSP2String(MIH_C_LINK_SCAN_RSP_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - buffer_index += sprintf(&bufP[buffer_index], "LINK_ADDR="); - buffer_index += MIH_C_LINK_ADDR2String(&dataP->link_addr, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], ", NETWORK_ID="); - buffer_index += MIH_C_NETWORK_ID2String(&dataP->network_id, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], ", SIG_STRENGTH="); - buffer_index += MIH_C_SIG_STRENGTH2String(&dataP->sig_strength, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_SCAN_RSP_encode(Bit_Buffer_t* bbP, MIH_C_LINK_SCAN_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ADDR_encode(bbP, &dataP->link_addr); - MIH_C_NETWORK_ID_encode(bbP, &dataP->network_id); - MIH_C_SIG_STRENGTH_encode(bbP, &dataP->sig_strength); -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_SCAN_RSP_decode(Bit_Buffer_t* bbP, MIH_C_LINK_SCAN_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ADDR_decode(bbP, &dataP->link_addr); - MIH_C_NETWORK_ID_decode(bbP, &dataP->network_id); - MIH_C_SIG_STRENGTH_decode(bbP, &dataP->sig_strength); -} - -//----------------------------------------------------------------------------- -void MIH_C_LINK_ACTION_RSP_encode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ID_encode(bbP, &dataP->link_id); - MIH_C_LINK_AC_RESULT_encode(bbP, &dataP->link_ac_result); - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - break; - - case 1: - MIH_C_LINK_SCAN_RSP_LIST_encode(bbP, &dataP->_union.link_scan_rsp_list); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_LINK_ACTION_RSP_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_ACTION_RSP_decode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ID_decode(bbP, &dataP->link_id); - MIH_C_LINK_AC_RESULT_decode(bbP, &dataP->link_ac_result); - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - break; - - case 1: - MIH_C_LINK_SCAN_RSP_LIST_decode(bbP, &dataP->_union.link_scan_rsp_list); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_LINK_ACTION_RSP_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_THRESHOLD2String(MIH_C_THRESHOLD_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "THRESHOLD_VAL="); - buffer_index += MIH_C_THRESHOLD_VAL2String(&dataP->threshold_val, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], ", THRESHOLD_XDIR="); - buffer_index += MIH_C_THRESHOLD_XDIR2String2(&dataP->threshold_xdir, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_THRESHOLD_encode(Bit_Buffer_t* bbP, MIH_C_THRESHOLD_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_THRESHOLD_VAL_encode(bbP, &dataP->threshold_val); - MIH_C_THRESHOLD_XDIR_encode(bbP, &dataP->threshold_xdir); -} -//----------------------------------------------------------------------------- -void MIH_C_THRESHOLD_decode(Bit_Buffer_t* bbP, MIH_C_THRESHOLD_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_THRESHOLD_VAL_decode(bbP, &dataP->threshold_val); - MIH_C_THRESHOLD_XDIR_decode(bbP, &dataP->threshold_xdir); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_PARAM_TYPE2String( MIH_C_LINK_PARAM_TYPE_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (dataP->choice) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "GENERIC PARAMETER: "); - buffer_index += MIH_C_LINK_PARAM_GEN2String2(&dataP->_union.link_param_gen, &bufP[buffer_index]); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "QOS PARAMETER: "); - break; - - case 2: - buffer_index += sprintf(&bufP[buffer_index], "GG PARAMETER: "); - break; - - case 3: - buffer_index += sprintf(&bufP[buffer_index], "EDGE PARAMETER: "); - break; - - case 4: - buffer_index += sprintf(&bufP[buffer_index], "ETH PARAMETER: "); - break; - - case 5: - buffer_index += sprintf(&bufP[buffer_index], "802_11 PARAMETER: "); - break; - - case 6: - buffer_index += sprintf(&bufP[buffer_index], "C2K PARAMETER: "); - break; - - case 7: - buffer_index += sprintf(&bufP[buffer_index], "FDD PARAMETER: "); - break; - - case 8: - buffer_index += sprintf(&bufP[buffer_index], "HRPD PARAMETER: "); - break; - - case 9: - buffer_index += sprintf(&bufP[buffer_index], "802_16 PARAMETER: "); - break; - - case 10: - buffer_index += sprintf(&bufP[buffer_index], "802_20 PARAMETER: "); - break; - - case 11: - buffer_index += sprintf(&bufP[buffer_index], "802_22 PARAMETER: "); - break; - - case 12: - buffer_index += sprintf(&bufP[buffer_index], "LTE PARAMETER: "); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "UNINITIALIZED LINK TYPE"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_PARAM_TYPE_encode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_TYPE_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_LINK_PARAM_GEN_encode(bbP, &dataP->_union.link_param_gen); - break; - - case 1: - MIH_C_LINK_PARAM_QOS_encode(bbP, &dataP->_union.link_param_qos); - break; - - case 2: - MIH_C_LINK_PARAM_GG_encode(bbP, &dataP->_union.link_param_gg); - break; - - case 3: - MIH_C_LINK_PARAM_EDGE_encode(bbP, &dataP->_union.link_param_edge); - break; - - case 4: - MIH_C_LINK_PARAM_ETH_encode(bbP, &dataP->_union.link_param_eth); - break; - - case 5: - MIH_C_LINK_PARAM_802_11_encode(bbP, &dataP->_union.link_param_802_11); - break; - - case 6: - MIH_C_LINK_PARAM_C2K_encode(bbP, &dataP->_union.link_param_c2k); - break; - - case 7: - MIH_C_LINK_PARAM_FDD_encode(bbP, &dataP->_union.link_param_fdd); - break; - - case 8: - MIH_C_LINK_PARAM_HRPD_encode(bbP, &dataP->_union.link_param_hrpd); - break; - - case 9: - MIH_C_LINK_PARAM_802_16_encode(bbP, &dataP->_union.link_param_802_16); - break; - - case 10: - MIH_C_LINK_PARAM_802_20_encode(bbP, &dataP->_union.link_param_802_20); - break; - - case 11: - MIH_C_LINK_PARAM_802_22_encode(bbP, &dataP->_union.link_param_802_22); - break; - - case 12: - MIH_C_LINK_PARAM_LTE_encode(bbP, &dataP->_union.link_param_lte); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_LINK_PARAM_TYPE_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_PARAM_TYPE_decode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_TYPE_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_LINK_PARAM_GEN_decode(bbP, &dataP->_union.link_param_gen); - break; - - case 1: - MIH_C_LINK_PARAM_QOS_decode(bbP, &dataP->_union.link_param_qos); - break; - - case 2: - MIH_C_LINK_PARAM_GG_decode(bbP, &dataP->_union.link_param_gg); - break; - - case 3: - MIH_C_LINK_PARAM_EDGE_decode(bbP, &dataP->_union.link_param_edge); - break; - - case 4: - MIH_C_LINK_PARAM_ETH_decode(bbP, &dataP->_union.link_param_eth); - break; - - case 5: - MIH_C_LINK_PARAM_802_11_decode(bbP, &dataP->_union.link_param_802_11); - break; - - case 6: - MIH_C_LINK_PARAM_C2K_decode(bbP, &dataP->_union.link_param_c2k); - break; - - case 7: - MIH_C_LINK_PARAM_FDD_decode(bbP, &dataP->_union.link_param_fdd); - break; - - case 8: - MIH_C_LINK_PARAM_HRPD_decode(bbP, &dataP->_union.link_param_hrpd); - break; - - case 9: - MIH_C_LINK_PARAM_802_16_decode(bbP, &dataP->_union.link_param_802_16); - break; - - case 10: - MIH_C_LINK_PARAM_802_20_decode(bbP, &dataP->_union.link_param_802_20); - break; - - case 11: - MIH_C_LINK_PARAM_802_22_decode(bbP, &dataP->_union.link_param_802_22); - break; - - case 12: - MIH_C_LINK_PARAM_LTE_decode(bbP, &dataP->_union.link_param_802_22); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_LINK_PARAM_TYPE_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_CFG_PARAM2String(MIH_C_LINK_CFG_PARAM_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "LINK_PARAM_TYPE="); - buffer_index += MIH_C_LINK_PARAM_TYPE2String(&dataP->link_param_type, &bufP[buffer_index]); - - switch (dataP->choice) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], ", CHOICE NULL"); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], ", TIMER_INTERVAL="); - buffer_index += MIH_C_TIMER_INTERVAL2String(&dataP->_union.timer_interval, &bufP[buffer_index]); - break; -#ifdef RAL_SAME_AS_MEDIEVAL_PROJECT_BUT_I_THINK_THIS_IS_AN_ERROR - - case 2: - buffer_index += sprintf(&bufP[buffer_index], ", LINK_SCAN_RSP_LIST="); - buffer_index += MIH_C_LINK_SCAN_RSP_LIST2String(&dataP->_union.link_scan_rsp_list, &bufP[buffer_index]); - break; -#endif - - default: - buffer_index += sprintf(&bufP[buffer_index], ", CHOICE UNINITIALIZED"); - } - - buffer_index += sprintf(&bufP[buffer_index], ", TH_ACTION="); - buffer_index += MIH_C_TH_ACTION2String2(&dataP->th_action, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], ", THRESHOLD_LIST={"); - buffer_index += MIH_C_THRESHOLD_LIST2String(&dataP->threshold_list, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "}"); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_CFG_PARAM_encode(Bit_Buffer_t* bbP, MIH_C_LINK_CFG_PARAM_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_PARAM_TYPE_encode(bbP, &dataP->link_param_type); - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - break; - - case 1: - MIH_C_TIMER_INTERVAL_encode(bbP, &dataP->_union.timer_interval); - break; -#ifdef RAL_SAME_AS_MEDIEVAL_PROJECT_BUT_I_THINK_THIS_IS_AN_ERROR - - case 2: - MIH_C_LINK_SCAN_RSP_LIST_encode(bbP, &dataP->_union.link_scan_rsp_list); - break; -#endif - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_LINK_CFG_PARAM_T %d\n", dataP->choice); - } - - MIH_C_TH_ACTION_encode(bbP, &dataP->th_action); - MIH_C_THRESHOLD_LIST_encode(bbP, &dataP->threshold_list); -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_CFG_PARAM_decode(Bit_Buffer_t* bbP, MIH_C_LINK_CFG_PARAM_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_PARAM_TYPE_decode(bbP, &dataP->link_param_type); - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - break; - - case 1: - MIH_C_TIMER_INTERVAL_decode(bbP, &dataP->_union.timer_interval); - break; -#ifdef RAL_SAME_AS_MEDIEVAL_PROJECT_BUT_I_THINK_THIS_IS_AN_ERROR - - case 2: - MIH_C_LINK_SCAN_RSP_LIST_decode(bbP, &dataP->_union.link_scan_rsp_list); - break; -#endif - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_LINK_CFG_PARAM_T %d\n", dataP->choice); - } - - MIH_C_TH_ACTION_decode(bbP, &dataP->th_action); - MIH_C_THRESHOLD_LIST_decode(bbP, &dataP->threshold_list); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_CFG_STATUS2String(MIH_C_LINK_CFG_STATUS_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "LINK_PARAM_TYPE="); - buffer_index += MIH_C_LINK_PARAM_TYPE2String(&dataP->link_param_type, &bufP[buffer_index]); - - buffer_index += sprintf(&bufP[buffer_index], ", THRESHOLD="); - buffer_index += MIH_C_THRESHOLD2String(&dataP->threshold, &bufP[buffer_index]); - - buffer_index += sprintf(&bufP[buffer_index], ", CONFIG_STATUS="); - buffer_index += MIH_C_CONFIG_STATUS2String(&dataP->config_status, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_CFG_STATUS_encode(Bit_Buffer_t* bbP, MIH_C_LINK_CFG_STATUS_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_PARAM_TYPE_encode(bbP, &dataP->link_param_type); - MIH_C_THRESHOLD_encode(bbP, &dataP->threshold); - MIH_C_CONFIG_STATUS_encode(bbP, &dataP->config_status); -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_CFG_STATUS_decode(Bit_Buffer_t* bbP, MIH_C_LINK_CFG_STATUS_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_PARAM_TYPE_decode(bbP, &dataP->link_param_type); - MIH_C_THRESHOLD_decode(bbP, &dataP->threshold); - MIH_C_CONFIG_STATUS_decode(bbP, &dataP->config_status); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_DESC_RSP2String(MIH_C_LINK_DESC_RSP_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (dataP->choice) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "NUM_COS="); - buffer_index += MIH_C_NUM_COS2String(&dataP->_union.num_cos, &bufP[buffer_index]); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "NUM_QUEUE="); - buffer_index += MIH_C_NUM_QUEUE2String(&dataP->_union.num_queue, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "LINK_DESC_RSP UNITIALIZED"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_DESC_RSP_encode(Bit_Buffer_t* bbP, MIH_C_LINK_DESC_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_NUM_COS_encode(bbP, &dataP->_union.num_cos); - break; - - case 1: - MIH_C_NUM_QUEUE_encode(bbP, &dataP->_union.num_queue); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_LINK_DESC_RSP_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_DESC_RSP_decode(Bit_Buffer_t* bbP, MIH_C_LINK_DESC_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_NUM_COS_decode(bbP, &dataP->_union.num_cos); - break; - - case 1: - MIH_C_NUM_QUEUE_decode(bbP, &dataP->_union.num_queue); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_LINK_DESC_RSP_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_PARAM2String(MIH_C_LINK_PARAM_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "LINK_PARAM_TYPE="); - buffer_index += MIH_C_LINK_PARAM_TYPE2String(&dataP->link_param_type, &bufP[buffer_index]); - - switch (dataP->choice) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], ", LINK_PARAM_VAL="); - buffer_index += MIH_C_LINK_PARAM_VAL2String(&dataP->_union.link_param_val, &bufP[buffer_index]); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], ", QOS_PARAM_VAL="); - buffer_index += MIH_C_QOS_PARAM_VAL2String(&dataP->_union.qos_param_val, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "LINK_PARAM UNITIALIZED"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_PARAM_encode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_PARAM_TYPE_encode(bbP, &dataP->link_param_type); - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_LINK_PARAM_VAL_encode(bbP, &dataP->_union.link_param_val); - break; - - case 1: - MIH_C_QOS_PARAM_VAL_encode(bbP, &dataP->_union.qos_param_val); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_LINK_PARAM_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_PARAM_decode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_PARAM_TYPE_decode(bbP, &dataP->link_param_type); - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_LINK_PARAM_VAL_decode(bbP, &dataP->_union.link_param_val); - break; - - case 1: - MIH_C_QOS_PARAM_VAL_decode(bbP, &dataP->_union.qos_param_val); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_LINK_PARAM_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_PARAM_RPT2String(MIH_C_LINK_PARAM_RPT_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "LINK_PARAM="); - buffer_index += MIH_C_LINK_PARAM2String(&dataP->link_param, &bufP[buffer_index]); - - switch (dataP->choice) { - case 0: - //buffer_index += sprintf(&bufP[buffer_index], ", CHOICE NULL"); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], ", THRESHOLD="); - buffer_index += MIH_C_THRESHOLD2String(&dataP->_union.threshold, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], ", LINK_PARAM_RPT UNITIALIZED"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_PARAM_RPT_encode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_RPT_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_PARAM_encode(bbP, &dataP->link_param); - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - break; - - case 1: - MIH_C_THRESHOLD_encode(bbP, &dataP->_union.threshold); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_LINK_PARAM_RPT_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_PARAM_RPT_decode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_RPT_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_PARAM_decode(bbP, &dataP->link_param); - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - break; - - case 1: - MIH_C_THRESHOLD_decode(bbP, &dataP->_union.threshold); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_LINK_PARAM_RPT_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_POA_LIST_encode(Bit_Buffer_t* bbP, MIH_C_LINK_POA_LIST_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ID_encode(bbP, &dataP->link_id); - MIH_C_LINK_ADDR_LIST_encode(bbP, &dataP->link_addr_list); -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_POA_LIST_decode(Bit_Buffer_t* bbP, MIH_C_LINK_POA_LIST_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ID_decode(bbP, &dataP->link_id); - MIH_C_LINK_ADDR_LIST_decode(bbP, &dataP->link_addr_list); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_STATES_RSP2String(MIH_C_LINK_STATES_RSP_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (dataP->choice) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "OPMODE="); - buffer_index += MIH_C_OPMODE2String2(&dataP->_union.op_mode, &bufP[buffer_index]); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "CHANNEL ID="); - buffer_index += MIH_C_CHANNEL_ID2String(&dataP->_union.channel_id, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "LINK_STATES_RSP UNITIALIZED"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_STATES_RSP_encode(Bit_Buffer_t* bbP, MIH_C_LINK_STATES_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_OPMODE_encode(bbP, &dataP->_union.op_mode); - break; - - case 1: - MIH_C_CHANNEL_ID_encode(bbP, &dataP->_union.channel_id); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_LINK_STATES_RSP_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_STATES_RSP_decode(Bit_Buffer_t* bbP, MIH_C_LINK_STATES_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_OPMODE_decode(bbP, &dataP->_union.op_mode); - break; - - case 1: - MIH_C_CHANNEL_ID_decode(bbP, &dataP->_union.channel_id); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_LINK_STATES_RSP_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_STATES_REQ2String2(MIH_C_LINK_STATES_REQ_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - if (*dataP & MIH_C_BIT_LINK_STATES_REQ_OP_MODE) buffer_index += sprintf(&bufP[buffer_index], "OPMODE"); - - if (*dataP & MIH_C_BIT_LINK_STATES_REQ_CHANNEL_ID) buffer_index += sprintf(&bufP[buffer_index], " CHANNEL_ID"); - - return buffer_index; -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_DESC_REQ2String2(MIH_C_LINK_DESC_REQ_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - if (*dataP & MIH_C_BIT_NUMBER_OF_CLASSES_OF_SERVICE_SUPPORTED) buffer_index += sprintf(&bufP[buffer_index], "NUM_OF_COS_SUPPORTED"); - - if (*dataP & MIH_C_BIT_NUMBER_OF_QUEUES_SUPPORTED) buffer_index += sprintf(&bufP[buffer_index], " NUM_OF_QUEUES_SUPPORTED"); - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_STATUS_REQ_encode(Bit_Buffer_t* bbP, MIH_C_LINK_STATUS_REQ_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_STATES_REQ_encode(bbP, &dataP->link_states_req); - MIH_C_LINK_PARAM_TYPE_LIST_encode(bbP, &dataP->link_param_type_list); - MIH_C_LINK_DESC_RSP_encode(bbP, &dataP->link_desc_rsp); -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_STATUS_REQ_decode(Bit_Buffer_t* bbP, MIH_C_LINK_STATUS_REQ_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_STATES_REQ_decode(bbP, &dataP->link_states_req); - MIH_C_LINK_PARAM_TYPE_LIST_decode(bbP, &dataP->link_param_type_list); - MIH_C_LINK_DESC_RSP_decode(bbP, &dataP->link_desc_rsp); -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_STATUS_RSP_encode(Bit_Buffer_t* bbP, MIH_C_LINK_STATUS_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_STATES_RSP_LIST_encode(bbP, &dataP->link_states_rsp_list); - MIH_C_LINK_PARAM_LIST_encode(bbP, &dataP->link_param_list); - MIH_C_LINK_DESC_RSP_LIST_encode(bbP, &dataP->link_desc_rsp_list); -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_STATUS_RSP_decode(Bit_Buffer_t* bbP, MIH_C_LINK_STATUS_RSP_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_STATES_RSP_LIST_decode(bbP, &dataP->link_states_rsp_list); - MIH_C_LINK_PARAM_LIST_decode(bbP, &dataP->link_param_list); - MIH_C_LINK_DESC_RSP_LIST_decode(bbP, &dataP->link_desc_rsp_list); -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_TUPLE_ID_encode(Bit_Buffer_t* bbP, MIH_C_LINK_TUPLE_ID_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ID_encode(bbP, &dataP->link_id); - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case MIH_C_LINK_TUPLE_ID_CHOICE_NULL: - break; - - case MIH_C_LINK_TUPLE_ID_CHOICE_LINK_ADDR: - MIH_C_LINK_ADDR_encode(bbP, &dataP->_union.link_addr); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_LINK_TUPLE_ID_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_TUPLE_ID_decode(Bit_Buffer_t* bbP, MIH_C_LINK_TUPLE_ID_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ID_decode(bbP, &dataP->link_id); - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case MIH_C_LINK_TUPLE_ID_CHOICE_NULL: - break; - - case MIH_C_LINK_TUPLE_ID_CHOICE_LINK_ADDR: - MIH_C_LINK_ADDR_decode(bbP, &dataP->_union.link_addr); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_LINK_TUPLE_ID_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_DET_INFO_encode(Bit_Buffer_t* bbP, MIH_C_LINK_DET_INFO_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_TUPLE_ID_encode(bbP, &dataP->link_tuple_id); - MIH_C_NETWORK_ID_encode(bbP, &dataP->network_id); - MIH_C_NET_AUX_ID_encode(bbP, &dataP->net_aux_id); - MIH_C_SIG_STRENGTH_encode(bbP, &dataP->sig_strength); - MIH_C_UNSIGNED_INT2_encode(bbP, &dataP->sinr); - MIH_C_LINK_DATA_RATE_encode(bbP, &dataP->link_data_rate); - MIH_C_LINK_MIHCAP_FLAG_encode(bbP, &dataP->link_mihcap_flag); - MIH_C_NET_CAPS_encode(bbP, &dataP->net_caps); - -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_DET_INFO_decode(Bit_Buffer_t* bbP, MIH_C_LINK_DET_INFO_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_TUPLE_ID_decode(bbP, &dataP->link_tuple_id); - MIH_C_NETWORK_ID_decode(bbP, &dataP->network_id); - MIH_C_NET_AUX_ID_decode(bbP, &dataP->net_aux_id); - MIH_C_SIG_STRENGTH_decode(bbP, &dataP->sig_strength); - MIH_C_UNSIGNED_INT2_decode(bbP, &dataP->sinr); - MIH_C_LINK_DATA_RATE_decode(bbP, &dataP->link_data_rate); - MIH_C_LINK_MIHCAP_FLAG_decode(bbP, &dataP->link_mihcap_flag); - MIH_C_NET_CAPS_decode(bbP, &dataP->net_caps); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_TH_ACTION2String2(MIH_C_TH_ACTION_T *actionP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (*actionP) { - case MIH_C_SET_NORMAL_THRESHOLD: - buffer_index += sprintf(&bufP[buffer_index], "SET_NORMAL_THRESHOLD"); - break; - - case MIH_C_SET_ONE_SHOT_THRESHOLD: - buffer_index += sprintf(&bufP[buffer_index], "SET_ONE_SHOT_THRESHOLD"); - break; - - case MIH_C_CANCEL_THRESHOLD: - buffer_index += sprintf(&bufP[buffer_index], "CANCEL_THRESHOLD"); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "UNKNOWN"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_THRESHOLD_XDIR2String2(MIH_C_THRESHOLD_XDIR_T *valP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch(*valP) { - case MIH_C_ABOVE_THRESHOLD: - buffer_index += sprintf(&bufP[buffer_index], "ABOVE_THRESHOLD"); - break; - - case MIH_C_BELOW_THRESHOLD: - buffer_index += sprintf(&bufP[buffer_index], "BELOW_THRESHOLD"); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "UNKNOWN"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_PARAM_GEN2String2(MIH_C_LINK_PARAM_GEN_T *valP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch(*valP) { - case MIH_C_LINK_PARAM_GEN_DATA_RATE: - buffer_index += sprintf(&bufP[buffer_index], "DATA_RATE"); - break; - - case MIH_C_LINK_PARAM_GEN_SIGNAL_STRENGTH: - buffer_index += sprintf(&bufP[buffer_index], "SIGNAL_STRENGTH"); - break; - - case MIH_C_LINK_PARAM_GEN_SINR: - buffer_index += sprintf(&bufP[buffer_index], "SINR"); - break; - - case MIH_C_LINK_PARAM_GEN_THROUGHPUT: - buffer_index += sprintf(&bufP[buffer_index], "THROUGHPUT"); - break; - - case MIH_C_LINK_PARAM_GEN_PACKET_ERROR_RATE: - buffer_index += sprintf(&bufP[buffer_index], "PACKET_ERROR_RATE"); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "UNKNOWN"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_AC_RESULT2String2(MIH_C_LINK_AC_RESULT_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (*dataP) { - case MIH_C_LINK_AC_RESULT_SUCCESS: - buffer_index += sprintf(&bufP[buffer_index], "SUCCESS"); - break; - - case MIH_C_LINK_AC_RESULT_FAILURE: - buffer_index += sprintf(&bufP[buffer_index], "FAILURE"); - break; - - case MIH_C_LINK_AC_RESULT_REFUSED: - buffer_index += sprintf(&bufP[buffer_index], "REFUSED"); - break; - - case MIH_C_LINK_AC_RESULT_INCAPABLE: - buffer_index += sprintf(&bufP[buffer_index], "INCAPABLE"); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "UNKNOWN"); - } - - return buffer_index; -} diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F9_data_types_for_qos_codec.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F9_data_types_for_qos_codec.c deleted file mode 100755 index 95647bb24f..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_F9_data_types_for_qos_codec.c +++ /dev/null @@ -1,274 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_F9_DATA_TYPES_FOR_QOS_CODEC_C -#include "MIH_C_F9_data_types_for_qos_codec.h" - -//----------------------------------------------------------------------------- -unsigned int MIH_C_MIN_PK_TX_DELAY2String(MIH_C_MIN_PK_TX_DELAY_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "COS = "); - buffer_index += MIH_C_COS_ID2String(&dataP->cos_id, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "VAL = "); - buffer_index += MIH_C_UNSIGNED_INT22String(&dataP->value, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_MIN_PK_TX_DELAY_encode(Bit_Buffer_t* bbP, MIH_C_MIN_PK_TX_DELAY_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_COS_ID_encode(bbP, &dataP->cos_id); - MIH_C_UNSIGNED_INT2_encode(bbP, &dataP->value); -} -//----------------------------------------------------------------------------- -void MIH_C_MIN_PK_TX_DELAY_decode(Bit_Buffer_t* bbP, MIH_C_MIN_PK_TX_DELAY_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_COS_ID_decode(bbP, &dataP->cos_id); - MIH_C_UNSIGNED_INT2_decode(bbP, &dataP->value); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_AVG_PK_TX_DELAY2String(MIH_C_AVG_PK_TX_DELAY_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "COS = "); - buffer_index += MIH_C_COS_ID2String(&dataP->cos_id, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "VAL = "); - buffer_index += MIH_C_UNSIGNED_INT22String(&dataP->value, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_AVG_PK_TX_DELAY_encode(Bit_Buffer_t* bbP, MIH_C_AVG_PK_TX_DELAY_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_COS_ID_encode(bbP, &dataP->cos_id); - MIH_C_UNSIGNED_INT2_encode(bbP, &dataP->value); -} -//----------------------------------------------------------------------------- -void MIH_C_AVG_PK_TX_DELAY_decode(Bit_Buffer_t* bbP, MIH_C_AVG_PK_TX_DELAY_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_COS_ID_decode(bbP, &dataP->cos_id); - MIH_C_UNSIGNED_INT2_decode(bbP, &dataP->value); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_MAX_PK_TX_DELAY2String(MIH_C_MAX_PK_TX_DELAY_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "COS = "); - buffer_index += MIH_C_COS_ID2String(&dataP->cos_id, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "VAL = "); - buffer_index += MIH_C_UNSIGNED_INT22String(&dataP->value, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_MAX_PK_TX_DELAY_encode(Bit_Buffer_t* bbP, MIH_C_MAX_PK_TX_DELAY_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_COS_ID_encode(bbP, &dataP->cos_id); - MIH_C_UNSIGNED_INT2_encode(bbP, &dataP->value); -} -//----------------------------------------------------------------------------- -void MIH_C_MAX_PK_TX_DELAY_decode(Bit_Buffer_t* bbP, MIH_C_MAX_PK_TX_DELAY_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_COS_ID_decode(bbP, &dataP->cos_id); - MIH_C_UNSIGNED_INT2_decode(bbP, &dataP->value); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_PK_DELAY_JITTER2String(MIH_C_PK_DELAY_JITTER_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "COS = "); - buffer_index += MIH_C_COS_ID2String(&dataP->cos_id, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "VAL = "); - buffer_index += MIH_C_UNSIGNED_INT22String(&dataP->value, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_PK_DELAY_JITTER_encode(Bit_Buffer_t* bbP, MIH_C_PK_DELAY_JITTER_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_COS_ID_encode(bbP, &dataP->cos_id); - MIH_C_UNSIGNED_INT2_encode(bbP, &dataP->value); -} -//----------------------------------------------------------------------------- -void MIH_C_PK_DELAY_JITTER_decode(Bit_Buffer_t* bbP, MIH_C_PK_DELAY_JITTER_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_COS_ID_decode(bbP, &dataP->cos_id); - MIH_C_UNSIGNED_INT2_decode(bbP, &dataP->value); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_PK_LOSS_RATE2String(MIH_C_PK_LOSS_RATE_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "COS = "); - buffer_index += MIH_C_COS_ID2String(&dataP->cos_id, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "VAL = "); - buffer_index += MIH_C_UNSIGNED_INT22String(&dataP->value, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_PK_LOSS_RATE_encode(Bit_Buffer_t* bbP, MIH_C_PK_LOSS_RATE_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_COS_ID_encode(bbP, &dataP->cos_id); - MIH_C_UNSIGNED_INT2_encode(bbP, &dataP->value); -} -//----------------------------------------------------------------------------- -void MIH_C_PK_LOSS_RATE_decode(Bit_Buffer_t* bbP, MIH_C_PK_LOSS_RATE_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_COS_ID_decode(bbP, &dataP->cos_id); - MIH_C_UNSIGNED_INT2_decode(bbP, &dataP->value); -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_QOS_PARAM_VAL2String(MIH_C_QOS_PARAM_VAL_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (dataP->choice) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "NUM_QOS_TYPES = "); - buffer_index += MIH_C_NUM_COS_TYPES2String(&dataP->_union.num_qos_types, &bufP[buffer_index]); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "MIN_PK_TX_DELAY_LIST = "); - buffer_index += MIH_C_MIN_PK_TX_DELAY_LIST2String(&dataP->_union.min_pk_tx_delay_list, &bufP[buffer_index]); - break; - - case 2: - buffer_index += sprintf(&bufP[buffer_index], "AVG_PK_TX_DELAY_LIST = "); - buffer_index += MIH_C_AVG_PK_TX_DELAY_LIST2String(&dataP->_union.avg_pk_tx_delay_list, &bufP[buffer_index]); - break; - - case 3: - buffer_index += sprintf(&bufP[buffer_index], "MAX_PK_TX_DELAY_LIST = "); - buffer_index += MIH_C_MAX_PK_TX_DELAY_LIST2String(&dataP->_union.max_pk_tx_delay_list, &bufP[buffer_index]); - break; - - case 4: - buffer_index += sprintf(&bufP[buffer_index], "PK_DELAY_JITTER_LIST = "); - buffer_index += MIH_C_PK_DELAY_JITTER_LIST2String(&dataP->_union.pk_delay_jitter_list, &bufP[buffer_index]); - break; - - case 5: - buffer_index += sprintf(&bufP[buffer_index], "PK_LOSS_RATE_LIST = "); - buffer_index += MIH_C_PK_LOSS_RATE_LIST2String(&dataP->_union.pk_loss_rate_list, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "QOS_PARAM_VAL UNITIALIZED"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_QOS_PARAM_VAL_encode(Bit_Buffer_t* bbP, MIH_C_QOS_PARAM_VAL_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_NUM_COS_TYPES_encode(bbP, &dataP->_union.num_qos_types); - break; - - case 1: - MIH_C_MIN_PK_TX_DELAY_LIST_encode(bbP, &dataP->_union.min_pk_tx_delay_list); - break; - - case 2: - MIH_C_AVG_PK_TX_DELAY_LIST_encode(bbP, &dataP->_union.avg_pk_tx_delay_list); - break; - - case 3: - MIH_C_MAX_PK_TX_DELAY_LIST_encode(bbP, &dataP->_union.max_pk_tx_delay_list); - break; - - case 4: - MIH_C_PK_DELAY_JITTER_LIST_encode(bbP, &dataP->_union.pk_delay_jitter_list); - break; - - case 5: - MIH_C_PK_LOSS_RATE_LIST_encode(bbP, &dataP->_union.pk_loss_rate_list); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_QOS_PARAM_VAL_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_QOS_PARAM_VAL_decode(Bit_Buffer_t* bbP, MIH_C_QOS_PARAM_VAL_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_NUM_COS_TYPES_encode(bbP, &dataP->_union.num_qos_types); - break; - - case 1: - MIH_C_MIN_PK_TX_DELAY_LIST_encode(bbP, &dataP->_union.min_pk_tx_delay_list); - break; - - case 2: - MIH_C_AVG_PK_TX_DELAY_LIST_decode(bbP, &dataP->_union.avg_pk_tx_delay_list); - break; - - case 3: - MIH_C_MAX_PK_TX_DELAY_LIST_decode(bbP, &dataP->_union.max_pk_tx_delay_list); - break; - - case 4: - MIH_C_PK_DELAY_JITTER_LIST_decode(bbP, &dataP->_union.pk_delay_jitter_list); - break; - - case 5: - MIH_C_PK_LOSS_RATE_LIST_decode(bbP, &dataP->_union.pk_loss_rate_list); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_QOS_PARAM_VAL_T %d\n", dataP->choice); - } -} - - - diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_L2_type_values_for_tlv_encoding.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_L2_type_values_for_tlv_encoding.c deleted file mode 100755 index b4e21ae575..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_L2_type_values_for_tlv_encoding.c +++ /dev/null @@ -1,356 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_L2_TYPE_VALUES_FOR_TLV_ENCODING_C -#include "MIH_C_L2_type_values_for_tlv_encoding.h" - -//----------------------------------------------------------------------------- -unsigned int MIH_C_TLV2String(MIH_C_TLV_TYPE_T *typeP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch(*typeP) { - case MIH_C_TLV_SOURCE_MIHF_ID: - buffer_index += sprintf(&bufP[buffer_index], "TLV_SOURCE_MIHF_ID"); - break; - - case MIH_C_TLV_DESTINATION_MIHF_ID: - buffer_index += sprintf(&bufP[buffer_index], "TLV_DESTINATION_MIHF_ID"); - break; - - case MIH_C_TLV_STATUS: - buffer_index += sprintf(&bufP[buffer_index], "TLV_STATUS"); - break; - - case MIH_C_TLV_LINK_TYPE: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_TYPE"); - break; - - case MIH_C_TLV_MIH_EVENT_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_MIH_EVENT_LIST"); - break; - - case MIH_C_TLV_MIH_COMMAND_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_MIH_COMMAND_LIST"); - break; - - case MIH_C_TLV_MIIS_QUERY_TYPE_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_MIIS_QUERY_TYPE_LIST"); - break; - - case MIH_C_TLV_TRANSPORT_OPTION_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_TRANSPORT_OPTION_LIST"); - break; - - case MIH_C_TLV_LINK_ADDRESS_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_ADDRESS_LIST"); - break; - - case MIH_C_TLV_MBB_HANDOVER_SUPPORT: - buffer_index += sprintf(&bufP[buffer_index], "TLV_MBB_HANDOVER_SUPPORT"); - break; - - case MIH_C_TLV_REGISTER_REQUEST_CODE: - buffer_index += sprintf(&bufP[buffer_index], "TLV_REGISTER_REQUEST_CODE"); - break; - - case MIH_C_TLV_VALID_TIME_INTERVAL: - buffer_index += sprintf(&bufP[buffer_index], "TLV_VALID_TIME_INTERVAL"); - break; - - case MIH_C_TLV_LINK_IDENTIFIER: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_IDENTIFIER"); - break; - - case MIH_C_TLV_NEW_LINK_IDENTIFIER: - buffer_index += sprintf(&bufP[buffer_index], "TLV_NEW_LINK_IDENTIFIER"); - break; - - case MIH_C_TLV_OLD_ACCESS_ROUTER: - buffer_index += sprintf(&bufP[buffer_index], "TLV_OLD_ACCESS_ROUTER"); - break; - - case MIH_C_TLV_NEW_ACCESS_ROUTER: - buffer_index += sprintf(&bufP[buffer_index], "TLV_NEW_ACCESS_ROUTER"); - break; - - case MIH_C_TLV_IP_RENEWAL_FLAG: - buffer_index += sprintf(&bufP[buffer_index], "TLV_IP_RENEWAL_FLAG"); - break; - - case MIH_C_TLV_MOBILITY_MANAGEMENT_SUPPORT: - buffer_index += sprintf(&bufP[buffer_index], "TLV_MOBILITY_MANAGEMENT_SUPPORT"); - break; - - case MIH_C_TLV_IP_ADDRESS_CONFIGURATION_METHODS: - buffer_index += sprintf(&bufP[buffer_index], "TLV_IP_ADDRESS_CONFIGURATION_METHODS"); - break; - - case MIH_C_TLV_LINK_DOWN_REASON_CODE: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_DOWN_REASON_CODE"); - break; - - case MIH_C_TLV_LINK_TIME_INTERVAL: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_TIME_INTERVAL"); - break; - - case MIH_C_TLV_LINK_GOING_DOWN_REASON_CODE: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_GOING_DOWN_REASON_CODE"); - break; - - case MIH_C_TLV_LINK_PARAMETER_REPORT_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_PARAMETER_REPORT_LIST"); - break; - - case MIH_C_TLV_DEVICE_STATES_REQUEST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_DEVICE_STATES_REQUEST"); - break; - - case MIH_C_TLV_LINK_IDENTIFIER_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_IDENTIFIER_LIST"); - break; - - case MIH_C_TLV_DEVICE_STATES_RESPONSE_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_DEVICE_STATES_RESPONSE_LIST"); - break; - - case MIH_C_TLV_GET_STATUS_REQUEST_SET: - buffer_index += sprintf(&bufP[buffer_index], "TLV_GET_STATUS_REQUEST_SET"); - break; - - case MIH_C_TLV_GET_STATUS_RESPONSE_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_GET_STATUS_RESPONSE_LIST"); - break; - - case MIH_C_TLV_CONFIGURE_REQUEST_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_CONFIGURE_REQUEST_LIST"); - break; - - case MIH_C_TLV_CONFIGURE_RESPONSE_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_CONFIGURE_RESPONSE_LIST"); - break; - - case MIH_C_TLV_LIST_OF_LINK_POA_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LIST_OF_LINK_POA_LIST"); - break; - - case MIH_C_TLV_PREFERRED_LINK_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_PREFERRED_LINK_LIST"); - break; - - case MIH_C_TLV_HANDOVER_RESOURCE_QUERY_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_HANDOVER_RESOURCE_QUERY_LIST"); - break; - - case MIH_C_TLV_HANDOVER_STATUS: - buffer_index += sprintf(&bufP[buffer_index], "TLV_HANDOVER_STATUS"); - break; - - case MIH_C_TLV_ACCESS_ROUTER_ADDRESS: - buffer_index += sprintf(&bufP[buffer_index], "TLV_ACCESS_ROUTER_ADDRESS"); - break; - - case MIH_C_TLV_DHCP_SERVER_ADDRESS: - buffer_index += sprintf(&bufP[buffer_index], "TLV_DHCP_SERVER_ADDRESS"); - break; - - case MIH_C_TLV_FA_ADDRESS: - buffer_index += sprintf(&bufP[buffer_index], "TLV_FA_ADDRESS"); - break; - - case MIH_C_TLV_LINK_ACTIONS_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_ACTIONS_LIST"); - break; - - case MIH_C_TLV_LINK_ACTIONS_RESULT_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_ACTIONS_RESULT_LIST"); - break; - - case MIH_C_TLV_HANDOVER_RESULT: - buffer_index += sprintf(&bufP[buffer_index], "TLV_HANDOVER_RESULT"); - break; - - case MIH_C_TLV_RESOURCE_STATUS: - buffer_index += sprintf(&bufP[buffer_index], "TLV_RESOURCE_STATUS"); - break; - - case MIH_C_TLV_RESOURCE_RETENTION_STATUS: - buffer_index += sprintf(&bufP[buffer_index], "TLV_RESOURCE_RETENTION_STATUS"); - break; - - case MIH_C_TLV_INFO_QUERY_BINARY_DATA_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_INFO_QUERY_BINARY_DATA_LIST"); - break; - - case MIH_C_TLV_INFO_QUERY_RDF_DATA_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_INFO_QUERY_RDF_DATA_LIST"); - break; - - case MIH_C_TLV_INFO_QUERY_RDF_SCHEMA_URL: - buffer_index += sprintf(&bufP[buffer_index], "TLV_INFO_QUERY_RDF_SCHEMA_URL"); - break; - - case MIH_C_TLV_INFO_QUERY_RDF_SCHEMA_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_INFO_QUERY_RDF_SCHEMA_LIST"); - break; - - case MIH_C_TLV_MAX_RESPONSE_SIZE: - buffer_index += sprintf(&bufP[buffer_index], "TLV_MAX_RESPONSE_SIZE"); - break; - - case MIH_C_TLV_INFO_RESPONSE_BINARY_DATA_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_INFO_RESPONSE_BINARY_DATA_LIST"); - break; - - case MIH_C_TLV_INFO_RESPONSE_RDF_DATA_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_INFO_RESPONSE_RDF_DATA_LIST"); - break; - - case MIH_C_TLV_INFO_RESPONSE_RDF_SCHEMA_URL_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_INFO_RESPONSE_RDF_SCHEMA_URL_LIST"); - break; - - case MIH_C_TLV_INFO_RESPONSE_RDF_SCHEMA_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_INFO_RESPONSE_RDF_SCHEMA_LIST"); - break; - - case MIH_C_TLV_MOBILE_NODE_MIHF_ID: - buffer_index += sprintf(&bufP[buffer_index], "TLV_MOBILE_NODE_MIHF_ID"); - break; - - case MIH_C_TLV_QUERY_RESOURCE_REPORT_FLAG: - buffer_index += sprintf(&bufP[buffer_index], "TLV_QUERY_RESOURCE_REPORT_FLAG"); - break; - - case MIH_C_TLV_EVENT_CONFIGURATION_INFO_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_EVENT_CONFIGURATION_INFO_LIST"); - break; - - case MIH_C_TLV_TARGET_NETWORK_INFO: - buffer_index += sprintf(&bufP[buffer_index], "TLV_TARGET_NETWORK_INFO"); - break; - - case MIH_C_TLV_LIST_OF_TARGET_NETWORK_INFO: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LIST_OF_TARGET_NETWORK_INFO"); - break; - - case MIH_C_TLV_ASSIGNED_RESOURCE_SET: - buffer_index += sprintf(&bufP[buffer_index], "TLV_ASSIGNED_RESOURCE_SET"); - break; - - case MIH_C_TLV_LINK_DETECTED_INFO_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_DETECTED_INFO_LIST"); - break; - - case MIH_C_TLV_MN_LINK_ID: - buffer_index += sprintf(&bufP[buffer_index], "TLV_MN_LINK_ID"); - break; - - case MIH_C_TLV_POA: - buffer_index += sprintf(&bufP[buffer_index], "TLV_POA"); - break; - - case MIH_C_TLV_UNAUTHENTICATED_INFORMATION_REQUEST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_UNAUTHENTICATED_INFORMATION_REQUEST"); - break; - - case MIH_C_TLV_NETWORK_TYPE: - buffer_index += sprintf(&bufP[buffer_index], "TLV_NETWORK_TYPE"); - break; - - case MIH_C_TLV_REQUESTED_RESOURCE_SET: - buffer_index += sprintf(&bufP[buffer_index], "TLV_REQUESTED_RESOURCE_SET"); - break; -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - - case MIH_C_TLV_LINK_EVENT_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_EVENT_LIST"); - break; - - case MIH_C_TLV_LINK_CMD_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_CMD_LIST"); - break; - - case MIH_C_TLV_LINK_PARAM_TYPE_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_PARAM_TYPE_LIST"); - break; - - case MIH_C_TLV_LINK_PARAMETERS_STATUS_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_PARAMETERS_STATUS_LIST"); - break; - - case MIH_C_TLV_LINK_STATES_REQ: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_STATES_REQ"); - break; - - case MIH_C_TLV_LINK_STATES_RSP_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_STATES_RSP_LIST"); - break; - - case MIH_C_TLV_LINK_DESC_REQ: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_DESC_REQ"); - break; - - case MIH_C_TLV_LINK_DESC_RSP_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_DESC_RSP_LIST"); - break; - - case MIH_C_TLV_LINK_ACTION: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_ACTION"); - break; - - case MIH_C_TLV_LINK_AC_RESULT: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_AC_RESULT"); - break; - - case MIH_C_TLV_LINK_SCAN_RSP_LIST: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_SCAN_RSP_LIST"); - break; - - case MIH_C_TLV_LINK_DET_INFO: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_DET_INFO"); - break; - - case MIH_C_TLV_LINK_INTERFACE_TYPE_ADDR: - buffer_index += sprintf(&bufP[buffer_index], "TLV_LINK_INTERFACE_TYPE_ADDR"); - break; - - case MIH_C_TLV_MOS_DSCV: - buffer_index += sprintf(&bufP[buffer_index], "TLV_MOS_DSCV"); - break; -#endif - - default: - buffer_index += sprintf(&bufP[buffer_index], "UNKNOWN TLV"); - } - - return buffer_index; -} diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_Medieval_extensions.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_Medieval_extensions.c deleted file mode 100755 index 079c80f890..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_Medieval_extensions.c +++ /dev/null @@ -1,671 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -#define MIH_C_INTERFACE -#define MIH_C_MEDIEVAL_EXTENSIONS_C -#include "MIH_C_Medieval_extensions.h" - -//----------------------------------------------------------------------------- -unsigned int MIH_C_PROTO2String(MIH_C_PROTO_T *protoP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (*protoP) { - case MIH_C_PROTO_TCP: - buffer_index += sprintf(&bufP[buffer_index], "TCP"); - break; - - case MIH_C_PROTO_UDP: - buffer_index += sprintf(&bufP[buffer_index], "UDP"); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "UNKNOWN_PROTO"); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_IP_TUPLE2String(MIH_C_IP_TUPLE_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - buffer_index += sprintf(&bufP[buffer_index], "IP_ADDR = "); - buffer_index += MIH_C_IP_ADDR2String(&dataP->ip_addr, &bufP[buffer_index]); - - buffer_index += sprintf(&bufP[buffer_index], "\nPORT = "); - buffer_index += MIH_C_PORT2String(&dataP->port, &bufP[buffer_index]); - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_IP_TUPLE_encode(Bit_Buffer_t* bbP, MIH_C_IP_TUPLE_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_IP_ADDR_encode(bbP, &dataP->ip_addr); - MIH_C_PORT_encode(bbP, &dataP->port); -} -//----------------------------------------------------------------------------- -void MIH_C_IP_TUPLE_decode(Bit_Buffer_t* bbP, MIH_C_IP_TUPLE_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_IP_ADDR_decode(bbP, &dataP->ip_addr); - MIH_C_PORT_decode(bbP, &dataP->port); -} -/*//----------------------------------------------------------------------------- -unsigned int MIH_C_FLOW_ID2String(MIH_C_FLOW_ID_T *dataP, char* bufP) { -//----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - buffer_index += sprintf(&bufP[buffer_index], "IP_TUPLE SRC = "); - buffer_index += MIH_C_IP_TUPLE2String(&dataP->source_addr, &bufP[buffer_index]); - - buffer_index += sprintf(&bufP[buffer_index], "\nIP_TUPLE DEST = "); - buffer_index += MIH_C_IP_TUPLE2String(&dataP->dest_addr, &bufP[buffer_index]); - - buffer_index += sprintf(&bufP[buffer_index], "\nPROTO = "); - buffer_index += MIH_C_PROTO2String(&dataP->transport_protocol, &bufP[buffer_index]); - return buffer_index; -} -//----------------------------------------------------------------------------- -inline void MIH_C_FLOW_ID_encode(Bit_Buffer_t* bbP, MIH_C_FLOW_ID_T *dataP) { -//----------------------------------------------------------------------------- - MIH_C_IP_TUPLE_encode(bbP, &dataP->source_addr); - MIH_C_IP_TUPLE_encode(bbP, &dataP->dest_addr); - MIH_C_PROTO_encode(bbP, &dataP->transport_protocol); -} -//----------------------------------------------------------------------------- -inline void MIH_C_FLOW_ID_decode(Bit_Buffer_t* bbP, MIH_C_FLOW_ID_T *dataP) { -//----------------------------------------------------------------------------- - MIH_C_IP_TUPLE_decode(bbP, &dataP->source_addr); - MIH_C_IP_TUPLE_decode(bbP, &dataP->dest_addr); - MIH_C_PROTO_decode(bbP, &dataP->transport_protocol); -}*/ -//----------------------------------------------------------------------------- -unsigned int MIH_C_MARK2String(MIH_C_MARK_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (dataP->choice) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "DSCP MASK = "); - buffer_index += MIH_C_BITMAP82String(&dataP->_union.dscp_mask, &bufP[buffer_index]); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "FLOW LABEL = "); - buffer_index += MIH_C_BITMAP242String(&dataP->_union.flow_label_mask, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "MARK UNINITIALIZED "); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_MARK_encode(Bit_Buffer_t* bbP, MIH_C_MARK_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_BITMAP8_encode(bbP, &dataP->_union.dscp_mask); - break; - - case 1: - MIH_C_BITMAP24_encode(bbP, &dataP->_union.flow_label_mask); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_MARK_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_MARK_decode(Bit_Buffer_t* bbP, MIH_C_MARK_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_BITMAP8_decode(bbP, &dataP->_union.dscp_mask); - break; - - case 1: - MIH_C_BITMAP24_decode(bbP, &dataP->_union.flow_label_mask); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_MARK_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_QOS2String(MIH_C_QOS_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (dataP->choice) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "MAX_DELAY = "); - buffer_index += MIH_C_MAX_DELAY2String(&dataP->_union.mark_qos.max_delay, &bufP[buffer_index]); - - buffer_index += sprintf(&bufP[buffer_index], "BITRATE = "); - buffer_index += MIH_C_BITRATE2String(&dataP->_union.mark_qos.bitrate, &bufP[buffer_index]); - - buffer_index += sprintf(&bufP[buffer_index], "JITTER = "); - buffer_index += MIH_C_JITTER2String(&dataP->_union.mark_qos.jitter, &bufP[buffer_index]); - - buffer_index += sprintf(&bufP[buffer_index], "PKT_LOSS_RATE = "); - buffer_index += MIH_C_PKT_LOSS_RATE2String(&dataP->_union.mark_qos.pkt_loss, &bufP[buffer_index]); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "COS = "); - buffer_index += MIH_C_COS2String(&dataP->_union.cos, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "QOS UNINITIALIZED "); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_QOS_encode(Bit_Buffer_t* bbP, MIH_C_QOS_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_MAX_DELAY_encode(bbP, &dataP->_union.mark_qos.max_delay); - MIH_C_BITRATE_encode(bbP, &dataP->_union.mark_qos.bitrate); - MIH_C_JITTER_encode(bbP, &dataP->_union.mark_qos.jitter); - MIH_C_PKT_LOSS_RATE_encode(bbP, &dataP->_union.mark_qos.pkt_loss); - break; - - case 1: - MIH_C_COS_encode(bbP, &dataP->_union.cos); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_QOS_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_QOS_decode(Bit_Buffer_t* bbP, MIH_C_QOS_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - MIH_C_MAX_DELAY_decode(bbP, &dataP->_union.mark_qos.max_delay); - MIH_C_BITRATE_decode(bbP, &dataP->_union.mark_qos.bitrate); - MIH_C_JITTER_decode(bbP, &dataP->_union.mark_qos.jitter); - MIH_C_PKT_LOSS_RATE_decode(bbP, &dataP->_union.mark_qos.pkt_loss); - break; - - case 1: - MIH_C_COS_decode(bbP, &dataP->_union.cos); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_QOS_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_RESOURCE_DESC2String(MIH_C_RESOURCE_DESC_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - buffer_index += sprintf(&bufP[buffer_index], "LINK_ID = "); - buffer_index += MIH_C_LINK_ID2String(&dataP->link_id, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nFLOW_ID = "); - buffer_index += MIH_C_FLOW_ID2String(&dataP->flow_id, &bufP[buffer_index]); - - switch (dataP->choice_link_data_rate) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "\nLINK_DATA_RATE = NULL"); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "\nLINK_DATA_RATE = "); - buffer_index += MIH_C_LINK_DATA_RATE2String(&dataP->_union_link_data_rate.link_data_rate, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "\nLINK_DATA_RATE UNINITIALIZED "); - } - - switch (dataP->choice_qos) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "\nQOS = NULL"); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "\nQOS = "); - buffer_index += MIH_C_QOS2String(&dataP->_union_qos.qos, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "\nQOS UNINITIALIZED "); - } - - switch (dataP->choice_jumbo_enable) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "\nJUMBO_ENABLE = NULL"); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "\nJUMBO_ENABLE = "); - buffer_index += MIH_C_JUMBO_ENABLE2String(&dataP->_union_jumbo_enable.jumbo_enable, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "\nJUMBO_ENABLE UNINITIALIZED "); - } - - switch (dataP->choice_multicast_enable) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "\nMULTICAST_ENABLE = NULL"); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "\nMULTICAST_ENABLE = "); - buffer_index += MIH_C_MULTICAST_ENABLE2String(&dataP->_union_multicast_enable.multicast_enable, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "\nMULTICAST_ENABLE UNINITIALIZED "); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_RESOURCE_DESC_encode(Bit_Buffer_t* bbP, MIH_C_RESOURCE_DESC_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ID_encode(bbP, &dataP->link_id); - MIH_C_FLOW_ID_encode(bbP, &dataP->flow_id); - - MIH_C_CHOICE_encode(bbP, &dataP->choice_link_data_rate); - - switch (dataP->choice_link_data_rate) { - case 0: - break; - - case 1: - MIH_C_LINK_DATA_RATE_encode(bbP, &dataP->_union_link_data_rate.link_data_rate); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE choice_link_data_rate OF MIH_C_RESOURCE_DESC_T %d\n", dataP->choice_link_data_rate); - } - - MIH_C_CHOICE_encode(bbP, &dataP->choice_qos); - - switch (dataP->choice_qos) { - case 0: - break; - - case 1: - MIH_C_QOS_encode(bbP, &dataP->_union_qos.qos); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE choice_qos OF MIH_C_RESOURCE_DESC_T %d\n", dataP->choice_qos); - } - - MIH_C_CHOICE_encode(bbP, &dataP->choice_jumbo_enable); - - switch (dataP->choice_jumbo_enable) { - case 0: - break; - - case 1: - MIH_C_JUMBO_ENABLE_encode(bbP, &dataP->_union_jumbo_enable.jumbo_enable); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE choice_jumbo_enable OF MIH_C_RESOURCE_DESC_T %d\n", dataP->choice_jumbo_enable); - } - - MIH_C_CHOICE_encode(bbP, &dataP->choice_multicast_enable); - - switch (dataP->choice_multicast_enable) { - case 0: - break; - - case 1: - MIH_C_MULTICAST_ENABLE_encode(bbP, &dataP->_union_multicast_enable.multicast_enable); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE choice_multicast_enable OF MIH_C_RESOURCE_DESC_T %d\n", dataP->choice_multicast_enable); - } -} -//----------------------------------------------------------------------------- -void MIH_C_RESOURCE_DESC_decode(Bit_Buffer_t* bbP, MIH_C_RESOURCE_DESC_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ID_decode(bbP, &dataP->link_id); - MIH_C_FLOW_ID_decode(bbP, &dataP->flow_id); - - MIH_C_CHOICE_decode(bbP, &dataP->choice_link_data_rate); - - switch (dataP->choice_link_data_rate) { - case 0: - break; - - case 1: - MIH_C_LINK_DATA_RATE_decode(bbP, &dataP->_union_link_data_rate.link_data_rate); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE choice_link_data_rate OF MIH_C_RESOURCE_DESC_T %d\n", dataP->choice_link_data_rate); - } - - MIH_C_CHOICE_decode(bbP, &dataP->choice_qos); - - switch (dataP->choice_qos) { - case 0: - break; - - case 1: - MIH_C_QOS_decode(bbP, &dataP->_union_qos.qos); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE choice_qos OF MIH_C_RESOURCE_DESC_T %d\n", dataP->choice_qos); - } - - MIH_C_CHOICE_decode(bbP, &dataP->choice_jumbo_enable); - - switch (dataP->choice_jumbo_enable) { - case 0: - break; - - case 1: - MIH_C_JUMBO_ENABLE_decode(bbP, &dataP->_union_jumbo_enable.jumbo_enable); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE choice_jumbo_enable OF MIH_C_RESOURCE_DESC_T %d\n", dataP->choice_jumbo_enable); - } - - MIH_C_CHOICE_decode(bbP, &dataP->choice_multicast_enable); - - switch (dataP->choice_multicast_enable) { - case 0: - break; - - case 1: - MIH_C_MULTICAST_ENABLE_decode(bbP, &dataP->_union_multicast_enable.multicast_enable); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE choice_multicast_enable OF MIH_C_RESOURCE_DESC_T %d\n", dataP->choice_multicast_enable); - } -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_FLOW_ATTRIBUTE2String(MIH_C_FLOW_ATTRIBUTE_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (dataP->choice_multicast_enable) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "MULTICAST_ENABLE = NULL"); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "MULTICAST_ENABLE = "); - buffer_index += MIH_C_MULTICAST_ENABLE2String(&dataP->_union_multicast_enable.multicast_enable, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "MULTICAST_ENABLE UNINITIALIZED "); - } - - switch (dataP->choice_mark_qos) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "\nMARK_QOS = NULL"); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "\nMARK = "); - buffer_index += MIH_C_MARK2String(&dataP->_union_mark_qos.mark_qos.mark, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nQOS = "); - buffer_index += MIH_C_QOS2String(&dataP->_union_mark_qos.mark_qos.qos, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "\nMARK_QOS UNINITIALIZED "); - } - - switch (dataP->choice_mark_drop_eligibility) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "\nMARK_DROP_ELIGIBILITY = NULL"); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "\nMARK = "); - buffer_index += MIH_C_MARK2String(&dataP->_union_mark_drop_eligibility.mark_drop_eligibility.mark, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nDROP_ELIGIBILITY = "); - buffer_index += MIH_C_DROP_ELIGIBILITY2String(&dataP->_union_mark_drop_eligibility.mark_drop_eligibility.drop_eligibility, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "\nMARK_DROP_ELIGIBILITY UNINITIALIZED "); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_FLOW_ATTRIBUTE_encode(Bit_Buffer_t* bbP, MIH_C_FLOW_ATTRIBUTE_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_FLOW_ID_encode(bbP, &dataP->flow_id); - - MIH_C_CHOICE_encode(bbP, &dataP->choice_multicast_enable); - - switch (dataP->choice_multicast_enable) { - case 0: - break; - - case 1: - MIH_C_MULTICAST_ENABLE_encode(bbP, &dataP->_union_multicast_enable.multicast_enable); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE choice_multicast_enable OF MIH_C_FLOW_ATTRIBUTE_T %d\n", dataP->choice_multicast_enable); - } - - MIH_C_CHOICE_encode(bbP, &dataP->choice_mark_qos); - - switch (dataP->choice_mark_qos) { - case 0: - break; - - case 1: - MIH_C_MARK_encode(bbP, &dataP->_union_mark_qos.mark_qos.mark); - MIH_C_QOS_encode(bbP, &dataP->_union_mark_qos.mark_qos.qos); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE choice_mark_qos OF MIH_C_FLOW_ATTRIBUTE_T %d\n", dataP->choice_mark_qos); - } - - MIH_C_CHOICE_encode(bbP, &dataP->choice_mark_drop_eligibility); - - switch (dataP->choice_mark_drop_eligibility) { - case 0: - break; - - case 1: - MIH_C_MARK_encode(bbP, &dataP->_union_mark_drop_eligibility.mark_drop_eligibility.mark); - MIH_C_DROP_ELIGIBILITY_encode(bbP, &dataP->_union_mark_drop_eligibility.mark_drop_eligibility.drop_eligibility); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE choice_mark_drop_eligibility OF MIH_C_FLOW_ATTRIBUTE_T %d\n", dataP->choice_mark_drop_eligibility); - } -} -//----------------------------------------------------------------------------- -void MIH_C_FLOW_ATTRIBUTE_decode(Bit_Buffer_t* bbP, MIH_C_FLOW_ATTRIBUTE_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_FLOW_ID_decode(bbP, &dataP->flow_id); - - MIH_C_CHOICE_decode(bbP, &dataP->choice_multicast_enable); - - switch (dataP->choice_multicast_enable) { - case 0: - break; - - case 1: - MIH_C_MULTICAST_ENABLE_decode(bbP, &dataP->_union_multicast_enable.multicast_enable); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE choice_multicast_enable OF MIH_C_FLOW_ATTRIBUTE_T %d\n", dataP->choice_multicast_enable); - } - - MIH_C_CHOICE_decode(bbP, &dataP->choice_mark_qos); - - switch (dataP->choice_mark_qos) { - case 0: - break; - - case 1: - MIH_C_MARK_decode(bbP, &dataP->_union_mark_qos.mark_qos.mark); - MIH_C_QOS_decode(bbP, &dataP->_union_mark_qos.mark_qos.qos); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE choice_mark_qos OF MIH_C_FLOW_ATTRIBUTE_T %d\n", dataP->choice_mark_qos); - } - - MIH_C_CHOICE_decode(bbP, &dataP->choice_mark_drop_eligibility); - - switch (dataP->choice_mark_drop_eligibility) { - case 0: - break; - - case 1: - MIH_C_MARK_decode(bbP, &dataP->_union_mark_drop_eligibility.mark_drop_eligibility.mark); - MIH_C_DROP_ELIGIBILITY_decode(bbP, &dataP->_union_mark_drop_eligibility.mark_drop_eligibility.drop_eligibility); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE choice_mark_drop_eligibility OF MIH_C_FLOW_ATTRIBUTE_T %d\n", dataP->choice_mark_drop_eligibility); - } -} -//----------------------------------------------------------------------------- -unsigned int MIH_C_LINK_AC_PARAM2String(MIH_C_LINK_AC_PARAM_T *dataP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - - switch (dataP->choice) { - case 0: - buffer_index += sprintf(&bufP[buffer_index], "NULL"); - break; - - case 1: - buffer_index += sprintf(&bufP[buffer_index], "FLOW_ATTRIBUTE="); - buffer_index += MIH_C_FLOW_ATTRIBUTE2String(&dataP->_union.flow_attribute, &bufP[buffer_index]); - break; - - case 2: - buffer_index += sprintf(&bufP[buffer_index], "RESOURCE_DESC="); - buffer_index += MIH_C_RESOURCE_DESC2String(&dataP->_union.resource_desc, &bufP[buffer_index]); - break; - - default: - buffer_index += sprintf(&bufP[buffer_index], "UNINITIALIZED "); - } - - return buffer_index; -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_AC_PARAM_encode(Bit_Buffer_t* bbP, MIH_C_LINK_AC_PARAM_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_encode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - break; - - case 1: - MIH_C_FLOW_ATTRIBUTE_encode(bbP, &dataP->_union.flow_attribute); - break; - - case 2: - MIH_C_RESOURCE_DESC_encode(bbP, &dataP->_union.resource_desc); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR ENCODING CHOICE OF MIH_C_LINK_AC_PARAM_T %d\n", dataP->choice); - } -} -//----------------------------------------------------------------------------- -void MIH_C_LINK_AC_PARAM_decode(Bit_Buffer_t* bbP, MIH_C_LINK_AC_PARAM_T *dataP) -{ - //----------------------------------------------------------------------------- - MIH_C_CHOICE_decode(bbP, &dataP->choice); - - switch (dataP->choice) { - case 0: - break; - - case 1: - MIH_C_FLOW_ATTRIBUTE_decode(bbP, &dataP->_union.flow_attribute); - break; - - case 2: - MIH_C_RESOURCE_DESC_decode(bbP, &dataP->_union.resource_desc); - break; - - default: - printf("[MIH_C] ERROR NO KNOWN VALUE FOR DECODING CHOICE OF MIH_C_LINK_AC_PARAM_T %d\n", dataP->choice); - } -} - -#endif diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_bit_buffer.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_bit_buffer.c deleted file mode 100755 index 1c91e0d429..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_bit_buffer.c +++ /dev/null @@ -1,528 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MRALLTEINT_BIT_BUFFER_C -//----------------------------------------------------------------------------- -#include <stdlib.h> -#include <assert.h> -#include <string.h> -#include <arpa/inet.h> -#include <stdio.h> -//----------------------------------------------------------------------------- -#include "MIH_C_bit_buffer.h" -//----------------------------------------------------------------------------- -Bit_Buffer_t* new_BitBuffer_0(void) -//----------------------------------------------------------------------------- -{ - Bit_Buffer_t* bb = malloc(sizeof(Bit_Buffer_t)); - bb->m_buffer_allocated_by_this = BIT_BUFFER_FALSE; - bb->m_buffer = 0; - bb->m_byte_position = 0; - bb->m_bit_mod_8_position = 0; - bb->m_capacity = 0; - bb->m_limit = 0; - return bb; -} -//----------------------------------------------------------------------------- -Bit_Buffer_t* new_BitBuffer_1(unsigned int capacityP) -//----------------------------------------------------------------------------- -{ - Bit_Buffer_t* bb = malloc(sizeof(Bit_Buffer_t)); - - bb->m_buffer_allocated_by_this = BIT_BUFFER_TRUE; - bb->m_buffer = malloc(capacityP); - memset(bb->m_buffer, 0, capacityP); - bb->m_byte_position = 0; - bb->m_bit_mod_8_position = 0; - bb->m_capacity = capacityP; - bb->m_limit = 0; - return bb; -} - -//----------------------------------------------------------------------------- -Bit_Buffer_t* new_BitBuffer_2(unsigned char* bufferP, unsigned int capacityP) -//----------------------------------------------------------------------------- -{ - Bit_Buffer_t* bb = malloc(sizeof(Bit_Buffer_t)); - bb->m_buffer_allocated_by_this = BIT_BUFFER_FALSE; - bb->m_buffer = bufferP; - bb->m_byte_position = 0; - bb->m_bit_mod_8_position = 0; - bb->m_limit = 0; - bb->m_capacity = capacityP; - return bb; -} - -//----------------------------------------------------------------------------- -void BitBuffer_wrap(Bit_Buffer_t* bbP, unsigned char* bufferP, unsigned int capacityP) -//----------------------------------------------------------------------------- -{ - if ((bbP->m_buffer != 0) && (bbP->m_buffer != bufferP)) { - free(bbP->m_buffer); - } - - bbP->m_buffer_allocated_by_this = BIT_BUFFER_FALSE; - bbP->m_buffer = bufferP; - bbP->m_byte_position = 0; - bbP->m_bit_mod_8_position = 0; - bbP->m_limit = capacityP; - bbP->m_capacity = capacityP; -} -//----------------------------------------------------------------------------- -u_int32_t BitBuffer_read32(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - return (u_int32_t)(BitBuffer_read(bbP, 32)); -} -//----------------------------------------------------------------------------- -u_int32_t BitBuffer_read32littleendian(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - return (u_int32_t)(ntohl(BitBuffer_read(bbP,32))); -} -//----------------------------------------------------------------------------- -u_int16_t BitBuffer_read16(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - return (u_int16_t)(BitBuffer_read(bbP,16)); -} -//----------------------------------------------------------------------------- -u_int16_t BitBuffer_read16littleendian(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - return (u_int16_t)(ntohs((u_int16_t)(BitBuffer_read(bbP, 16)))); -} -//----------------------------------------------------------------------------- -unsigned char BitBuffer_read8(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - - return (u_int8_t)(BitBuffer_read(bbP,8)); -} -//----------------------------------------------------------------------------- -u_int8_t BitBuffer_readBool(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - return (u_int8_t)(BitBuffer_read(bbP,1)); -} -//----------------------------------------------------------------------------- -u_int32_t BitBuffer_read(Bit_Buffer_t* bbP, const unsigned int nb_bitsP) -//----------------------------------------------------------------------------- -{ - u_int64_t data_l = 0; - u_int32_t mask = 0xFFFFFFFFL; - u_int32_t bit_index_l = bbP->m_bit_mod_8_position; - int32_t bit_length_l = nb_bitsP; - u_int32_t byte_index_l = bbP->m_byte_position; - u_int32_t rotate_l = 0; - - //cout << dec << "BitBuffer_read(" << nb_bitsP << ")"<< endl; - if (BitBuffer_isCheckReadOverflowOK(bbP, nb_bitsP)) { - if (nb_bitsP > (sizeof(unsigned long)*8)) { - printf("[MIH_C] ERROR BitBuffer_read nb bits too large - must be <= sizeof(long int)*8"); - } else { - do { - data_l = data_l << 8; - data_l = data_l | (unsigned long long int)(bbP->m_buffer[byte_index_l++]); - //cout << hex << "data_l= " << data_l << endl; - bit_length_l -= (8- bit_index_l); - bit_index_l = 0; - rotate_l += 8; - } while (bit_length_l > 0); - - //cout << dec << "data_l rotated >> by " << rotate_l - bbP->m_bit_mod_8_position - nb_bitsP << " bits " << endl; - //cout << hex << "data_l masked >> by " << (mask >> (sizeof(unsigned long)*8 - nb_bitsP)) << endl; - data_l = (data_l >> (rotate_l - bbP->m_bit_mod_8_position - nb_bitsP)) & - (mask >> (sizeof(unsigned long)*8 - nb_bitsP)); - bbP->m_bit_mod_8_position = (bbP->m_bit_mod_8_position + nb_bitsP) % 8; - - if (bbP->m_bit_mod_8_position == 0) { - bbP->m_byte_position = byte_index_l; - } else { - bbP->m_byte_position = byte_index_l - 1; - } - } - - return (u_int32_t)(data_l); - } - - return (u_int32_t)(data_l); -} -//----------------------------------------------------------------------------- -u_int32_t BitBuffer_readlittleendian(Bit_Buffer_t* bbP, const unsigned int nb_bitsP) -//----------------------------------------------------------------------------- -{ - if (nb_bitsP > 24) { - return ntohl(BitBuffer_read(bbP,nb_bitsP)); - } else if (nb_bitsP > 16) { - return ntohl(BitBuffer_read(bbP,nb_bitsP) << 8); - } else if (nb_bitsP > 8) { - return ntohl(BitBuffer_read(bbP,nb_bitsP) << 16); - } else { - return ntohl(BitBuffer_read(bbP,nb_bitsP) << 24); - } -} -//----------------------------------------------------------------------------- -void BitBuffer_readMem(Bit_Buffer_t* bbP, u_int8_t* destP, unsigned int nb_bytesP) -//----------------------------------------------------------------------------- -{ - assert (bbP->m_bit_mod_8_position == 0); // TO DO - - if (BitBuffer_isCheckReadOverflowOK(bbP,nb_bytesP *8)) { - memcpy(destP, &bbP->m_buffer[bbP->m_byte_position], nb_bytesP); - bbP->m_byte_position += nb_bytesP; - } -} - -//----------------------------------------------------------------------------- -void BitBuffer_write32(Bit_Buffer_t* bbP, u_int32_t valueP) -//----------------------------------------------------------------------------- -{ - if (BitBuffer_isCheckWriteOverflowOK(bbP, sizeof(u_int32_t)*8)) { - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 24)); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 16)); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 8)); - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - } -} -//----------------------------------------------------------------------------- -void BitBuffer_write32littleendian(Bit_Buffer_t* bbP, u_int32_t valueP) -//----------------------------------------------------------------------------- -{ - if (BitBuffer_isCheckWriteOverflowOK(bbP,sizeof(u_int32_t)*8)) { - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 8)); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 16)); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 24)); - } -} -//----------------------------------------------------------------------------- -void BitBuffer_write16littleendian(Bit_Buffer_t* bbP, u_int16_t valueP) -//----------------------------------------------------------------------------- -{ - if (BitBuffer_isCheckWriteOverflowOK(bbP,sizeof(u_int16_t)*8)) { - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 8)); - } -} -//----------------------------------------------------------------------------- -void BitBuffer_write16(Bit_Buffer_t* bbP, u_int16_t valueP) -//----------------------------------------------------------------------------- -{ - if (BitBuffer_isCheckWriteOverflowOK(bbP,sizeof(u_int16_t)*8)) { - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 8)); - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - } -} -//----------------------------------------------------------------------------- -void BitBuffer_write8(Bit_Buffer_t* bbP, u_int8_t valueP) -//----------------------------------------------------------------------------- -{ - if (BitBuffer_isCheckWriteOverflowOK(bbP,sizeof(u_int8_t)*8)) { - if (bbP->m_bit_mod_8_position == 0) { - bbP->m_buffer[bbP->m_byte_position++] = valueP; - } else { - bbP->m_buffer[bbP->m_byte_position] = (valueP >> bbP->m_bit_mod_8_position) | bbP->m_buffer[bbP->m_byte_position]; - bbP->m_byte_position++; - bbP->m_buffer[bbP->m_byte_position] = valueP << (8 - bbP->m_bit_mod_8_position); - } - } -} -//----------------------------------------------------------------------------- -void BitBuffer_writeBool(Bit_Buffer_t* bbP, u_int8_t valueP) -//----------------------------------------------------------------------------- -{ - if (BitBuffer_isCheckWriteOverflowOK(bbP,1)) { - if (valueP) { - BitBuffer_write8b(bbP,(u_int8_t)(0x01), 1); - } else { - BitBuffer_write8b(bbP,(u_int8_t)(0x00), 1); - } - } -} -//----------------------------------------------------------------------------- -void BitBuffer_writeMem(Bit_Buffer_t* bbP, u_int8_t* startP, unsigned int nb_bytesP) -//----------------------------------------------------------------------------- -{ - assert (bbP->m_bit_mod_8_position == 0); // TO DO - - if (BitBuffer_isCheckWriteOverflowOK(bbP,nb_bytesP *8)) { - memcpy(&bbP->m_buffer[bbP->m_byte_position], startP, nb_bytesP); - bbP->m_byte_position += nb_bytesP; - } -} -//----------------------------------------------------------------------------- -void BitBuffer_write8b(Bit_Buffer_t* bbP, u_int8_t valueP, unsigned int nb_bitsP) -//----------------------------------------------------------------------------- -{ - assert(nb_bitsP <= 8); - - if (nb_bitsP == 0) return; - - if (BitBuffer_isCheckWriteOverflowOK(bbP,nb_bitsP)) { - valueP = valueP & ((u_int8_t)(0xFF) >> (8 - nb_bitsP)); - - //std::cout << "BitBuffer_write char " << (u_int32_t)(valueP) << " " << nb_bitsP << " bits" << std::endl; - if (nb_bitsP > (sizeof(unsigned char)*8)) { - printf("[MIH_C] ERROR BitBuffer_write nb bits too large - must be <= sizeof(char)*8"); - } else { - if (bbP->m_bit_mod_8_position == 0) { - if (nb_bitsP == (sizeof(unsigned char)*8)) { - BitBuffer_write8(bbP, valueP); - } else { - bbP->m_buffer[bbP->m_byte_position] = valueP << (8 - nb_bitsP); - bbP->m_bit_mod_8_position += nb_bitsP; - } - } else { - bbP->m_buffer[bbP->m_byte_position] = ((valueP << (8 - nb_bitsP)) >> bbP->m_bit_mod_8_position) | bbP->m_buffer[bbP->m_byte_position]; - - if ((bbP->m_bit_mod_8_position + nb_bitsP)>= (sizeof(unsigned char)*8)) { - bbP->m_byte_position++; - bbP->m_buffer[bbP->m_byte_position] = valueP << (16 - bbP->m_bit_mod_8_position - nb_bitsP); - } - - bbP->m_bit_mod_8_position = (nb_bitsP + bbP->m_bit_mod_8_position) % (sizeof(unsigned char)*8); - } - } - } -} -//----------------------------------------------------------------------------- -void BitBuffer_writelittleendian(Bit_Buffer_t* bbP, u_int8_t valueP, unsigned int nb_bitsP) -//----------------------------------------------------------------------------- -{ - BitBuffer_write8b(bbP,valueP, nb_bitsP); -} -//----------------------------------------------------------------------------- -void BitBuffer_write16b(Bit_Buffer_t* bbP, u_int16_t valueP, unsigned int nb_bitsP) -//----------------------------------------------------------------------------- -{ - assert(nb_bitsP <= 16); - - if (BitBuffer_isCheckWriteOverflowOK(bbP,nb_bitsP)) { - valueP = valueP & ((u_int16_t)(0xFFFF) >> (16 - nb_bitsP)); - - if (nb_bitsP > (sizeof (u_int16_t)*8)) { - printf("[MIH_C] ERROR BitBuffer_write nb bits too large - must be <= sizeof (short)*8"); - } else { - if (nb_bitsP > 8) { - //BitBuffer_write8b(bbP,(u_int8_t)(valueP >> (8 - (16-nb_bitsP))), nb_bitsP - 8); - BitBuffer_write8b(bbP,(u_int8_t)(valueP >> 8), nb_bitsP - 8); - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - } else if (nb_bitsP > 0) { - BitBuffer_write8b(bbP,(u_int8_t)(valueP), nb_bitsP); - } - } - } -} -//----------------------------------------------------------------------------- -void BitBuffer_writelittleendian16b(Bit_Buffer_t* bbP, u_int16_t valueP, unsigned int nb_bitsP) -//----------------------------------------------------------------------------- -{ - assert(nb_bitsP <= 16); - - if (BitBuffer_isCheckWriteOverflowOK(bbP,nb_bitsP)) { - valueP = valueP & ((u_int16_t)(0xFFFF) >> (16 - nb_bitsP)); - - if (nb_bitsP > (sizeof (u_int16_t)*8)) { - printf("[MIH_C] ERROR BitBuffer_write nb bits too large - must be <= sizeof (short)*8"); - } else { - if (nb_bitsP > 8) { - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - //BitBuffer_write8b(bbP,(u_int8_t)(valueP >> (8 - (16-nb_bitsP))), nb_bitsP - 8); - BitBuffer_write8b(bbP,(u_int8_t)(valueP >> 8), nb_bitsP - 8); - } else if (nb_bitsP > 0) { - BitBuffer_write8b(bbP,(u_int8_t)(valueP), nb_bitsP); - } - } - } -} -//----------------------------------------------------------------------------- -void BitBuffer_write32b(Bit_Buffer_t* bbP, u_int32_t valueP, unsigned int nb_bitsP) -//----------------------------------------------------------------------------- -{ - assert(nb_bitsP <= 32); - - if (BitBuffer_isCheckWriteOverflowOK(bbP,nb_bitsP)) { - valueP = valueP & ((u_int32_t)(0xFFFFFFFF) >> (32 - nb_bitsP)); - - if (nb_bitsP > (sizeof (u_int32_t)*8)) { - printf("[MIH_C] ERROR BitBuffer_write nb bits too large - must be <= sizeof (int)*8"); - } else { - if (nb_bitsP > 24) { - //BitBuffer_write8b(bbP,(u_int8_t)(valueP >> (24 - (32-nb_bitsP))), nb_bitsP - 24); - BitBuffer_write8b(bbP,(u_int8_t)(valueP >> 24), nb_bitsP - 24); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 16)); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 8)); - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - } else if (nb_bitsP > 16) { - //BitBuffer_write8b(bbP,(u_int8_t)(valueP >> (16 - (24-nb_bitsP))), nb_bitsP - 16); - BitBuffer_write8b(bbP,(u_int8_t)(valueP >> 16), nb_bitsP - 16); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 8)); - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - } else if (nb_bitsP > 8) { - //BitBuffer_write8b(bbP,(u_int8_t)(valueP >> (8 - (16-nb_bitsP))), nb_bitsP - 8); - BitBuffer_write8b(bbP,(u_int8_t)(valueP >> 8), nb_bitsP - 8); - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - } else if (nb_bitsP > 0) { - BitBuffer_write8b(bbP,(u_int8_t)(valueP), nb_bitsP); - } - } - } -} -//----------------------------------------------------------------------------- -void BitBuffer_writelittleendian32b(Bit_Buffer_t* bbP, u_int32_t valueP, unsigned int nb_bitsP) -//----------------------------------------------------------------------------- -{ - assert(nb_bitsP <= 32); - - if (BitBuffer_isCheckWriteOverflowOK(bbP,nb_bitsP)) { - valueP = valueP & ((u_int32_t)(0xFFFFFFFF) >> (32 - nb_bitsP)); - - if (nb_bitsP > (sizeof (u_int32_t)*8)) { - printf("[MIH_C] ERROR BitBuffer_write nb bits too large - must be <= sizeof (int)*8"); - } else { - if (nb_bitsP > 24) { - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 8)); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 16)); - BitBuffer_write8b(bbP,(u_int8_t)(valueP >> 24), nb_bitsP - 24); - //BitBuffer_write8b(bbP,(u_int8_t)(valueP >> (24 - (32-nb_bitsP))), nb_bitsP - 24); - } else if (nb_bitsP > 16) { - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - BitBuffer_write8(bbP,(u_int8_t)(valueP >> 8)); - BitBuffer_write8b(bbP,(u_int8_t)(valueP >> 16), nb_bitsP - 16); - //BitBuffer_write8b(bbP,(u_int8_t)(valueP >> (16 - (24-nb_bitsP))), nb_bitsP - 16); - } else if (nb_bitsP > 8) { - BitBuffer_write8(bbP,(u_int8_t)(valueP)); - BitBuffer_write8b(bbP,(u_int8_t)(valueP >> 8), nb_bitsP - 8); - //BitBuffer_write8b(bbP,(u_int8_t)(valueP >> (8 - (16-nb_bitsP))), nb_bitsP - 8); - } else if (nb_bitsP > 0) { - BitBuffer_write8b(bbP,(u_int8_t)(valueP), nb_bitsP); - } - } - } -} -//----------------------------------------------------------------------------- -void BitBuffer_rewind(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - bbP->m_byte_position = 0; - bbP->m_bit_mod_8_position = 0; -} -//----------------------------------------------------------------------------- -void BitBuffer_rewind_to(Bit_Buffer_t* bbP, unsigned int byte_positionP) -//----------------------------------------------------------------------------- -{ - bbP->m_byte_position = byte_positionP; - bbP->m_bit_mod_8_position = 0; -} -//----------------------------------------------------------------------------- -void BitBuffer_write_shift_last_n_bytes_right(Bit_Buffer_t* bbP, unsigned int nb_bytes_to_shiftP, unsigned int hole_sizeP) -//----------------------------------------------------------------------------- -{ - unsigned int index = 0; - - if (nb_bytes_to_shiftP >= bbP->m_byte_position) return; - - if ((bbP->m_byte_position + hole_sizeP) > bbP->m_capacity) return; - - while (index < nb_bytes_to_shiftP) { - bbP->m_buffer[bbP->m_byte_position -1 - index + hole_sizeP] = bbP->m_buffer[bbP->m_byte_position -1 - index]; - index += 1; - } -} -//----------------------------------------------------------------------------- -void BitBuffer_reset(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - BitBuffer_rewind(bbP); - bbP->m_limit = 0; - - if (bbP->m_buffer != 0) { - memset(bbP->m_buffer, 0, bbP->m_capacity); - } -} -//----------------------------------------------------------------------------- -unsigned char* BitBuffer_getNextFreePosition(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - return &(bbP->m_buffer[bbP->m_byte_position]); -} -//----------------------------------------------------------------------------- -unsigned int BitBuffer_getPosition(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - return (bbP->m_byte_position + (bbP->m_bit_mod_8_position +7)/8); -} -//----------------------------------------------------------------------------- -void BitBuffer_addLimitOffset(Bit_Buffer_t* bbP, unsigned int offsetP) -//----------------------------------------------------------------------------- -{ - bbP->m_limit += offsetP; -} -//----------------------------------------------------------------------------- -unsigned int BitBuffer_getNumFreeBytes(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - return bbP->m_capacity - (bbP->m_byte_position + (bbP->m_bit_mod_8_position +7)/8); -} -//----------------------------------------------------------------------------- -u_int8_t BitBuffer_isCheckWriteOverflowOK(Bit_Buffer_t* bbP, unsigned int nb_bitsP) -//----------------------------------------------------------------------------- -{ - if ((bbP->m_byte_position + (bbP->m_bit_mod_8_position + nb_bitsP+7)/8) < bbP->m_capacity) { - return BIT_BUFFER_TRUE; - } else { - //throw std::out_of_range("Exception in class BitBuffer cannot write more, no more space available"); - return BIT_BUFFER_FALSE; - } -} -//----------------------------------------------------------------------------- -u_int8_t BitBuffer_isCheckReadOverflowOK(Bit_Buffer_t* bbP, unsigned int nb_bitsP) -//----------------------------------------------------------------------------- -{ - if ((bbP->m_byte_position + (bbP->m_bit_mod_8_position + nb_bitsP)/8) <= bbP->m_limit) { - return BIT_BUFFER_TRUE; - } else { - //throw std::out_of_range("Exception in class BitBuffer cannot read more - end of buffer reached"); - return BIT_BUFFER_FALSE; - } -} -//----------------------------------------------------------------------------- -void free_BitBuffer(Bit_Buffer_t* bbP) -//----------------------------------------------------------------------------- -{ - //std::cout << "~BitBuffer()" << std::endl; - if (bbP->m_buffer_allocated_by_this == BIT_BUFFER_TRUE) { - free(bbP->m_buffer); - } - - free(bbP); -} diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_header_codec.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_header_codec.c deleted file mode 100755 index 58f94b474b..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_header_codec.c +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_HEADER_CODEC_C -#include "MIH_C_header_codec.h" -//----------------------------------------------------------------------------- -int MIH_C_HEADER2String(MIH_C_HEADER_T* headerP, char* bufP) -{ - //----------------------------------------------------------------------------- - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "HEADER.version: "); - buffer_index += MIH_C_VERSION2String(&headerP->version, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nHEADER.ack_req: "); - buffer_index += MIH_C_ACK_REQ2String(&headerP->ack_req, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nHEADER.ack_rsp: "); - buffer_index += MIH_C_ACK_RSP2String(&headerP->ack_rsp, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nHEADER.uir: "); - buffer_index += MIH_C_UIR2String(&headerP->uir, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nHEADER.more_fragment: "); - buffer_index += MIH_C_M2String(&headerP->more_fragment, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nHEADER.fragment_number: "); - buffer_index += MIH_C_FN2String(&headerP->more_fragment, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nHEADER.service_identifier: "); - buffer_index += MIH_C_SID2String(&headerP->service_identifier, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nHEADER.operation_code: "); - buffer_index += MIH_C_OPCODE2String(&headerP->operation_code, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nHEADER.action_identifier: "); - buffer_index += MIH_C_AID2String(&headerP->action_identifier, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nHEADER.transaction_id: "); - buffer_index += MIH_C_TRANSACTION_ID2String(&headerP->transaction_id, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nHEADER.payload_length: "); - buffer_index += MIH_C_VARIABLE_PAYLOAD_LENGTH2String(&headerP->payload_length, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - return buffer_index; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Header_Encode(Bit_Buffer_t* bbP, MIH_C_HEADER_T* headerP) -{ - //----------------------------------------------------------------------------- - u_int8_t reserved = 0; - int status ; - - if ((bbP != NULL) && (headerP != NULL)) { - status = MIH_HEADER_ENCODE_OK; - BitBuffer_write8b (bbP, headerP->version, 4); - BitBuffer_writeBool (bbP, headerP->ack_req); - BitBuffer_writeBool (bbP, headerP->ack_rsp); - BitBuffer_writeBool (bbP, headerP->uir); - BitBuffer_writeBool (bbP, headerP->more_fragment); - BitBuffer_write8b (bbP, headerP->fragment_number, 7); - BitBuffer_writeBool (bbP, reserved); - BitBuffer_write8b (bbP, headerP->service_identifier, 4); - BitBuffer_write8b (bbP, headerP->operation_code, 2); - BitBuffer_write16b (bbP, headerP->action_identifier, 10); - BitBuffer_write8b (bbP, reserved, 4); - BitBuffer_write16b (bbP, headerP->transaction_id, 12); - BitBuffer_write16 (bbP, headerP->payload_length); - /*DEBUG_ENCODE("%s: version 0x%02X\n", __FUNCTION__, headerP->version); - DEBUG_ENCODE("%s: ack_req 0x%02X\n", __FUNCTION__, headerP->ack_req); - DEBUG_ENCODE("%s: ack_rsp 0x%02X\n", __FUNCTION__, headerP->ack_rsp); - DEBUG_ENCODE("%s: uir 0x%02X\n", __FUNCTION__, headerP->uir); - DEBUG_ENCODE("%s: more_fragment 0x%02X\n", __FUNCTION__, headerP->more_fragment); - DEBUG_ENCODE("%s: reserved 0x%02X\n", __FUNCTION__, reserved); - DEBUG_ENCODE("%s: service_identifier 0x%02X\n", __FUNCTION__, headerP->service_identifier); - DEBUG_ENCODE("%s: operation_code 0x%02X\n", __FUNCTION__, headerP->operation_code); - DEBUG_ENCODE("%s: action_identifier 0x%04X\n", __FUNCTION__, headerP->action_identifier); - DEBUG_ENCODE("%s: reserved 0x%02X\n", __FUNCTION__, reserved); - DEBUG_ENCODE("%s: transaction_id 0x%04X\n", __FUNCTION__, headerP->transaction_id); - DEBUG_ENCODE("%s: payload_length 0x%02X\n", __FUNCTION__, headerP->payload_length);*/ - - // may be check for validity of header field -> set MIH_HEADER_DECODE_FAILURE - if (BitBuffer_isCheckWriteOverflowOK(bbP, 0) == BIT_BUFFER_FALSE) { - memset(headerP, 0, sizeof(MIH_C_HEADER_T)); - return MIH_HEADER_ENCODE_TOO_SHORT; - } else if (status == MIH_HEADER_ENCODE_FAILURE) { - memset(headerP, 0, sizeof(MIH_C_HEADER_T)); - return MIH_HEADER_ENCODE_FAILURE; - } else { - return MIH_HEADER_ENCODE_OK; - } - } else { - memset(headerP, 0, sizeof(MIH_C_HEADER_T)); - return MIH_HEADER_ENCODE_BAD_PARAMETER; - } -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Header_Decode(Bit_Buffer_t* bbP, MIH_C_HEADER_T* headerP) -{ - //----------------------------------------------------------------------------- - u_int8_t reserved ; - int status ; - - if ((bbP != NULL) && (headerP != NULL)) { - status = MIH_HEADER_DECODE_OK; - headerP->version = (MIH_C_VERSION_T)BitBuffer_read(bbP, 4); - headerP->ack_req = (MIH_C_ACK_REQ_T)BitBuffer_readBool(bbP); - headerP->ack_rsp = (MIH_C_ACK_RSP_T)BitBuffer_readBool(bbP); - headerP->uir = (MIH_C_UIR_T)BitBuffer_readBool(bbP); - headerP->more_fragment = (MIH_C_M_T)BitBuffer_readBool(bbP); - headerP->fragment_number = (MIH_C_FN_T)BitBuffer_read(bbP, 7); - reserved = BitBuffer_readBool(bbP); - headerP->service_identifier = (MIH_C_SID_T) BitBuffer_read(bbP, 4); - headerP->operation_code = (MIH_C_OPCODE_T) BitBuffer_read(bbP, 2); - headerP->action_identifier = (MIH_C_AID_T) BitBuffer_read(bbP, 10); - reserved = BitBuffer_read(bbP, 4); - headerP->transaction_id = (MIH_C_TRANSACTION_ID_T) BitBuffer_read(bbP, 12); - headerP->payload_length = (MIH_C_VARIABLE_PAYLOAD_LENGTH_T)BitBuffer_read16(bbP); - - /*DEBUG_DECODE("%s: version 0x%02X\n", __FUNCTION__, headerP->version); - DEBUG_DECODE("%s: ack_req 0x%02X\n", __FUNCTION__, headerP->ack_req); - DEBUG_DECODE("%s: ack_rsp 0x%02X\n", __FUNCTION__, headerP->ack_rsp); - DEBUG_DECODE("%s: uir 0x%02X\n", __FUNCTION__, headerP->uir); - DEBUG_DECODE("%s: more_fragment 0x%02X\n", __FUNCTION__, headerP->more_fragment); - DEBUG_DECODE("%s: reserved 0x%02X\n", __FUNCTION__, reserved); - DEBUG_DECODE("%s: service_identifier 0x%02X\n", __FUNCTION__, headerP->service_identifier); - DEBUG_DECODE("%s: operation_code 0x%02X\n", __FUNCTION__, headerP->operation_code); - DEBUG_DECODE("%s: action_identifier 0x%04X\n", __FUNCTION__, headerP->action_identifier); - DEBUG_DECODE("%s: reserved 0x%02X\n", __FUNCTION__, reserved); - DEBUG_DECODE("%s: transaction_id 0x%04X\n", __FUNCTION__, headerP->transaction_id); - DEBUG_DECODE("%s: payload_length 0x%02X\n", __FUNCTION__, headerP->payload_length);*/ - // may be check for validity of header field -> set MIH_HEADER_DECODE_FAILURE - - if (BitBuffer_isCheckReadOverflowOK(bbP, 0) == BIT_BUFFER_FALSE) { - memset(headerP, 0, sizeof(MIH_C_HEADER_T)); - return MIH_HEADER_DECODE_TOO_SHORT; - } else if (status == MIH_HEADER_DECODE_FAILURE) { - memset(headerP, 0, sizeof(MIH_C_HEADER_T)); - return MIH_HEADER_DECODE_FAILURE; - } else { - return MIH_HEADER_DECODE_OK; - } - } else { - memset(headerP, 0, sizeof(MIH_C_HEADER_T)); - return MIH_HEADER_DECODE_BAD_PARAMETER; - } -} diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_log.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_log.c deleted file mode 100755 index 3720d306c2..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_log.c +++ /dev/null @@ -1,190 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_LOG_C -/* -//----------------------------------------------------------------------------- -#include "MIH_C_log.h" -//----------------------------------------------------------------------------- -#define LOG_BUFF_SIZE 2048 -static char g_log_buffer_time[24]; -static char g_log_buffer[LOG_BUFF_SIZE]; -static int g_bypass_header; -//----------------------------------------------------------------------------- -char* getTimeStamp4Log() -//----------------------------------------------------------------------------- -{ - int len; - struct timespec time_spec; - unsigned int time_now_micros; - unsigned int time_now_s; - clock_gettime (CLOCK_REALTIME, &time_spec); - time_now_s = (unsigned int) time_spec.tv_sec % 3600; - time_now_micros = (unsigned int) time_spec.tv_nsec/1000; - //len=snprintf(g_log_buffer_time,24, "%06d:%06d", time_now_s, time_now_micros); - len=snprintf(g_log_buffer_time,24, "%03d:%03d", time_now_s, time_now_micros); - return g_log_buffer_time; -} -//----------------------------------------------------------------------------- -int is_newline( char *str, int size){ -//----------------------------------------------------------------------------- - int i; - for ( i = 0; i < size; i++ ) { - if ( str[i] == '\n' ) - return 1; - } - // if we get all the way to here, there must not have been a newline! - return 0; -} - -// Initialize logging system -int MIH_C_log_init(unsigned int log_outputP) { -//----------------------------------------------------------------------------- - g_mih_c_log_output = log_outputP; - - - g_log_level2string[LOG_EMERG] = "EMERG"; - g_log_level2string[LOG_ALERT] = "ALERT"; - g_log_level2string[LOG_CRIT] = "CRIT "; - g_log_level2string[LOG_ERR] = "ERR "; - g_log_level2string[LOG_WARNING] = "WARN "; - g_log_level2string[LOG_NOTICE] = "NOTCE"; - g_log_level2string[LOG_INFO] = "INFO "; - g_log_level2string[LOG_DEBUG] = "DEBUG"; - - g_bypass_header = 0; - - switch (g_mih_c_log_output){ - case LOG_TO_CONSOLE: - printf("***** mRAL V%s logging \n\n",MIH_C_VERSION); - break; - case LOG_TO_FILE: - g_mih_c_log_file = fopen(MIH_C_LOGFILE_NAME,"w"); //start over new file - if (g_mih_c_log_file == NULL){ - perror ("MIH_C_log_init - error opening file"); - exit(1); - } - fprintf(g_mih_c_log_file, "***** V%s starting logging \n\n",MIH_C_VERSION); - fflush(g_mih_c_log_file); - break; - case LOG_TO_SYSTEM: - openlog(MIH_C_SYSLOG_NAME, LOG_PID, LOG_LOCAL7); - syslog(LOG_NOTICE, "***** V%s starting logging \n\n",MIH_C_VERSION); - break; - default: - printf("MIH_C_log_init: log_outputP error %d", log_outputP); - } - return 0; -} - -//----------------------------------------------------------------------------- -// Log messages according to user settings -int MIH_C_log_record(int levelP, const char * log_msgP, ...) { -//----------------------------------------------------------------------------- - struct timespec time_spec; - unsigned int time_now_micros; - unsigned int time_now_s; - va_list log_ap; - int len; - - - switch (g_mih_c_log_output){ - case LOG_TO_CONSOLE: - va_start(log_ap, log_msgP); - len = vsnprintf(g_log_buffer, LOG_BUFF_SIZE-1, log_msgP, log_ap); - va_end(log_ap); - if (g_bypass_header == 0) { - clock_gettime (CLOCK_REALTIME, &time_spec); - time_now_s = (unsigned int) time_spec.tv_sec; - time_now_micros = (unsigned int) time_spec.tv_nsec/1000; - printf("[%06d:%06d][%s][%s] ", time_now_s, time_now_micros, MIH_C_SYSLOG_NAME, g_log_level2string[levelP]); - } - printf("%s",g_log_buffer); - fflush(stdout); - fflush(stderr); - if (is_newline(g_log_buffer,len) == 0 ){ - g_bypass_header = 1; - } else { - g_bypass_header = 0; - } - break; - case LOG_TO_FILE: - va_start(log_ap, log_msgP); - len = vsnprintf(g_log_buffer, LOG_BUFF_SIZE-1, log_msgP, log_ap); - va_end(log_ap); - if (g_bypass_header == 0) { - clock_gettime (CLOCK_REALTIME, &time_spec); - time_now_s = (unsigned int) time_spec.tv_sec; - time_now_micros = (unsigned int) time_spec.tv_nsec/1000; - fprintf(g_mih_c_log_file, "[%06d:%06d][%s][%s] ", time_now_s, time_now_micros, MIH_C_SYSLOG_NAME, g_log_level2string[levelP]); - } - fprintf(g_mih_c_log_file, "%s", g_log_buffer); - fflush(g_mih_c_log_file); - if (is_newline(g_log_buffer,len) == 0 ){ - g_bypass_header = 1; - } else { - g_bypass_header = 0; - } - break; - case LOG_TO_SYSTEM: - va_start(log_ap, log_msgP); - syslog(levelP, log_msgP, log_ap); - va_end(log_ap); - return 0; - break; - default: - printf("MIH_C_log_record: level error %d", levelP); - } - return 0; -} -//----------------------------------------------------------------------------- -// Close logging system -int MIH_C_log_exit(void) { -//----------------------------------------------------------------------------- - switch (g_mih_c_log_output){ - case LOG_TO_CONSOLE: - printf("***** stopping logging \n\n"); - break; - case LOG_TO_FILE: - fprintf(g_mih_c_log_file, "***** stopping logging \n\n"); - fflush(g_mih_c_log_file); - fclose(g_mih_c_log_file); - break; - case LOG_TO_SYSTEM: - syslog(LOG_NOTICE, "***** stopping logging \n\n"); - closelog(); - break; - default: - printf("MIH_C_log_exit: output unrecognized error %d", g_mih_c_log_output); - } - return 0; -} -*/ - diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_msg_codec.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_msg_codec.c deleted file mode 100755 index 27597d6a49..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_msg_codec.c +++ /dev/null @@ -1,1201 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_MSG_CODEC_C -#include "MIH_C_msg_codec.h" - -//----------------------------------------------------------------------------- -MIH_C_TRANSACTION_ID_T MIH_C_get_new_transaction_id(void) -{ - //----------------------------------------------------------------------------- - // no need now for mutex - g_transaction_id_generator += 1; - return g_transaction_id_generator; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Decode_Link_Capability_Discover_request(Bit_Buffer_t* bbP, MIH_C_Message_Link_Capability_Discover_request_t *messageP) -{ - //----------------------------------------------------------------------------- - int status; - MIH_C_TLV_TYPE_T tlv; - u_int16_t length; - - // SOURCE - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_SOURCE_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->source); - } else { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_FAILURE @ MIH_C_TLV_SOURCE_MIHF_ID\n", __FUNCTION__); - return MIH_MESSAGE_DECODE_FAILURE; - } - - // DESTINATION - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_DESTINATION_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->destination); - } else { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_FAILURE @ MIH_C_TLV_DESTINATION_MIHF_ID\n", __FUNCTION__); - return MIH_MESSAGE_DECODE_FAILURE; - } - - status = MIH_C_Link_Primitive_Decode_Link_Capability_Discover_request(bbP, &messageP->primitive); - - if (status == MIH_PRIMITIVE_DECODE_OK) { - printf("[MIH_C] %s() -> MIH_MESSAGE_DECODE_OK \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_OK; - } - - if (status == MIH_PRIMITIVE_DECODE_TOO_SHORT) { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_TOO_SHORT \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_TOO_SHORT; - } - - if (status == MIH_PRIMITIVE_DECODE_FAILURE) { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_FAILURE \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_FAILURE; - } - - if (status == MIH_PRIMITIVE_DECODE_BAD_PARAMETER) { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_BAD_PARAMETER \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - return status; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Link_Capability_Discover_request2String(MIH_C_Message_Link_Capability_Discover_request_t *messageP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "\n--------------------------------------------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- MESSAGE Link_Capability_Discover.request -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - buffer_index += MIH_C_HEADER2String(&messageP->header, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "-------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "SOURCE: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->source, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nDESTINATION: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->destination, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - buffer_index += MIH_C_Link_Primitive_Link_Capability_Discover_request2String(&messageP->primitive, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - return buffer_index; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Decode_Link_Event_Subscribe_request(Bit_Buffer_t* bbP, MIH_C_Message_Link_Event_Subscribe_request_t *messageP) -{ - //----------------------------------------------------------------------------- - int status; - MIH_C_TLV_TYPE_T tlv; - u_int16_t length; - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_SOURCE_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->source); - } else { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_FAILURE @ MIH_C_TLV_SOURCE_MIHF_ID\n", __FUNCTION__); - return MIH_MESSAGE_DECODE_FAILURE; - } - - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_DESTINATION_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->destination); - } else { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_FAILURE @ MIH_C_TLV_DESTINATION_MIHF_ID\n", __FUNCTION__); - return MIH_MESSAGE_DECODE_FAILURE; - } - - status = MIH_C_Link_Primitive_Decode_Link_Event_Subscribe_request(bbP, &messageP->primitive); - - if (status == MIH_PRIMITIVE_DECODE_OK) { - printf("[MIH_C] %s() -> MIH_MESSAGE_DECODE_OK \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_OK; - } - - if (status == MIH_PRIMITIVE_DECODE_TOO_SHORT) { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_TOO_SHORT \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_TOO_SHORT; - } - - if (status == MIH_PRIMITIVE_DECODE_FAILURE) { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_FAILURE \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_FAILURE; - } - - if (status == MIH_PRIMITIVE_DECODE_BAD_PARAMETER) { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_BAD_PARAMETER \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - return status; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Link_Event_Subscribe_request2String(MIH_C_Message_Link_Event_Subscribe_request_t *messageP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "\n--------------------------------------------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- MESSAGE Link_Event_Subscribe.request -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - buffer_index += MIH_C_HEADER2String(&messageP->header, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "-------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "SOURCE: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->source, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nDESTINATION: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->destination, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - buffer_index += MIH_C_Link_Primitive_Link_Event_Subscribe_request2String(&messageP->primitive, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - return buffer_index; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Decode_Link_Event_Unsubscribe_request(Bit_Buffer_t* bbP, MIH_C_Message_Link_Event_Unsubscribe_request_t *messageP) -{ - //----------------------------------------------------------------------------- - int status; - MIH_C_TLV_TYPE_T tlv; - u_int16_t length; - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_SOURCE_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->source); - } else { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_FAILURE @ MIH_C_TLV_SOURCE_MIHF_ID\n", __FUNCTION__); - return MIH_PRIMITIVE_DECODE_FAILURE; - } - - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_DESTINATION_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->destination); - } else { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_FAILURE @ MIH_C_TLV_DESTINATION_MIHF_ID\n", __FUNCTION__); - return MIH_PRIMITIVE_DECODE_FAILURE; - } - - status = MIH_C_Link_Primitive_Decode_Link_Event_Unsubscribe_request(bbP, &messageP->primitive); - - if (status == MIH_PRIMITIVE_DECODE_OK) { - printf("[MIH_C] %s() -> MIH_MESSAGE_DECODE_OK \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_OK; - } - - if (status == MIH_PRIMITIVE_DECODE_TOO_SHORT) { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_TOO_SHORT \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_TOO_SHORT; - } - - if (status == MIH_PRIMITIVE_DECODE_FAILURE) { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_FAILURE \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_FAILURE; - } - - if (status == MIH_PRIMITIVE_DECODE_BAD_PARAMETER) { - printf("[MIH_C] ERROR %s() -> MIH_MESSAGE_DECODE_BAD_PARAMETER \n", __FUNCTION__); - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - return status; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Link_Event_Unsubscribe_request2String(MIH_C_Message_Link_Event_Unsubscribe_request_t *messageP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "\n--------------------------------------------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- MESSAGE Link_Event_Unsubscribe.request -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - buffer_index += MIH_C_HEADER2String(&messageP->header, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "-------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "SOURCE: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->source, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nDESTINATION: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->destination, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - buffer_index += MIH_C_Link_Primitive_Link_Event_Unsubscribe_request2String(&messageP->primitive, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - return buffer_index; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Decode_Link_Get_Parameters_request(Bit_Buffer_t* bbP, MIH_C_Message_Link_Get_Parameters_request_t *messageP) -{ - //----------------------------------------------------------------------------- - int status; - MIH_C_TLV_TYPE_T tlv; - u_int16_t length; - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_SOURCE_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->source); - } else { - return MIH_PRIMITIVE_DECODE_FAILURE; - } - - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_DESTINATION_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->destination); - } else { - return MIH_PRIMITIVE_DECODE_FAILURE; - } - - status = MIH_C_Link_Primitive_Decode_Link_Get_Parameters_request(bbP, &messageP->primitive); - - if (status == MIH_PRIMITIVE_DECODE_OK) { - return MIH_MESSAGE_DECODE_OK; - } - - if (status == MIH_PRIMITIVE_DECODE_TOO_SHORT) { - return MIH_MESSAGE_DECODE_TOO_SHORT; - } - - if (status == MIH_PRIMITIVE_DECODE_FAILURE) { - return MIH_MESSAGE_DECODE_FAILURE; - } - - if (status == MIH_PRIMITIVE_DECODE_BAD_PARAMETER) { - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - return status; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Link_Get_Parameters_request2String(MIH_C_Message_Link_Get_Parameters_request_t *messageP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "\n--------------------------------------------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- MESSAGE Link_Get_Parameters.request -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - buffer_index += MIH_C_HEADER2String(&messageP->header, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "-------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "SOURCE: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->source, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nDESTINATION: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->destination, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - buffer_index += MIH_C_Link_Primitive_Link_Get_Parameters_request2String(&messageP->primitive, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - return buffer_index; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Decode_Link_Configure_Thresholds_request(Bit_Buffer_t* bbP, MIH_C_Message_Link_Configure_Thresholds_request_t *messageP) -{ - //----------------------------------------------------------------------------- - int status; - MIH_C_TLV_TYPE_T tlv; - u_int16_t length; - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_SOURCE_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->source); - } else { - return MIH_PRIMITIVE_DECODE_FAILURE; - } - - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_DESTINATION_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->destination); - } else { - return MIH_PRIMITIVE_DECODE_FAILURE; - } - - status = MIH_C_Link_Primitive_Decode_Link_Configure_Thresholds_request(bbP, &messageP->primitive); - - if (status == MIH_PRIMITIVE_DECODE_OK) { - return MIH_MESSAGE_DECODE_OK; - } - - if (status == MIH_PRIMITIVE_DECODE_TOO_SHORT) { - return MIH_MESSAGE_DECODE_TOO_SHORT; - } - - if (status == MIH_PRIMITIVE_DECODE_FAILURE) { - return MIH_MESSAGE_DECODE_FAILURE; - } - - if (status == MIH_PRIMITIVE_DECODE_BAD_PARAMETER) { - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - return status; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Link_Configure_Thresholds_request2String(MIH_C_Message_Link_Configure_Thresholds_request_t *messageP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "\n--------------------------------------------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- MESSAGE Link_Configure_Threshold.request -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - buffer_index += MIH_C_HEADER2String(&messageP->header, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "-------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "SOURCE: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->source, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nDESTINATION: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->destination, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - buffer_index += MIH_C_Link_Primitive_Link_Configure_Thresholds_request2String(&messageP->primitive, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - return buffer_index; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Decode_Link_Action_request(Bit_Buffer_t* bbP, MIH_C_Message_Link_Action_request_t *messageP) -{ - //----------------------------------------------------------------------------- - int status; - MIH_C_TLV_TYPE_T tlv; - u_int16_t length; - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_SOURCE_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->source); - } else { - return MIH_PRIMITIVE_DECODE_FAILURE; - } - - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - if (tlv == MIH_C_TLV_DESTINATION_MIHF_ID) { - MIH_C_MIHF_ID_decode(bbP, &messageP->destination); - } else { - return MIH_PRIMITIVE_DECODE_FAILURE; - } - - status = MIH_C_Link_Primitive_Decode_Link_Action_request(bbP, &messageP->primitive); - - if (status == MIH_PRIMITIVE_DECODE_OK) { - return MIH_MESSAGE_DECODE_OK; - } - - if (status == MIH_PRIMITIVE_DECODE_TOO_SHORT) { - return MIH_MESSAGE_DECODE_TOO_SHORT; - } - - if (status == MIH_PRIMITIVE_DECODE_FAILURE) { - return MIH_MESSAGE_DECODE_FAILURE; - } - - if (status == MIH_PRIMITIVE_DECODE_BAD_PARAMETER) { - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - return status; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Link_Action_request2String(MIH_C_Message_Link_Action_request_t *messageP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "\n--------------------------------------------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- MESSAGE Link_Action.request -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - buffer_index += MIH_C_HEADER2String(&messageP->header, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "-------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "SOURCE: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->source, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nDESTINATION: "); - buffer_index += MIH_C_MIHF_ID2String(&messageP->destination, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - buffer_index += MIH_C_Link_Primitive_Link_Action_request2String(&messageP->primitive, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------------------------------------------\n"); - return buffer_index; -} -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Link_Register_indication(Bit_Buffer_t* bbP, MIH_C_Message_Link_Register_indication_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - MIH_C_Link_Primitive_Encode_Link_Register_indication(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} -#endif -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Link_Detected_indication(Bit_Buffer_t* bbP, MIH_C_Message_Link_Detected_indication_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - MIH_C_Link_Primitive_Encode_Link_Detected_indication(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Link_Up_indication(Bit_Buffer_t* bbP, MIH_C_Message_Link_Up_indication_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - MIH_C_Link_Primitive_Encode_Link_Up_indication(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Link_Parameters_Report_indication(Bit_Buffer_t* bbP, MIH_C_Message_Link_Parameters_Report_indication_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - MIH_C_Link_Primitive_Encode_Link_Parameters_Report_indication(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Link_Going_Down_indication(Bit_Buffer_t* bbP, MIH_C_Message_Link_Going_Down_indication_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - MIH_C_Link_Primitive_Encode_Link_Going_Down_indication(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Link_Down_indication(Bit_Buffer_t* bbP, MIH_C_Message_Link_Down_indication_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - MIH_C_Link_Primitive_Encode_Link_Down_indication(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Link_Action_confirm(Bit_Buffer_t* bbP, MIH_C_Message_Link_Action_confirm_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - MIH_C_Link_Primitive_Encode_Link_Action_confirm(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Capability_Discover_confirm(Bit_Buffer_t* bbP, MIH_C_Message_Link_Capability_Discover_confirm_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - //-------------------------------------------------------------------------- - MIH_C_Link_Primitive_Encode_Link_Capability_Discover_confirm(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Event_Subscribe_confirm(Bit_Buffer_t* bbP, MIH_C_Message_Link_Event_Subscribe_confirm_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - //-------------------------------------------------------------------------- - MIH_C_Link_Primitive_Encode_Link_Event_Subscribe_confirm(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Event_Unsubscribe_confirm(Bit_Buffer_t* bbP, MIH_C_Message_Link_Event_Unsubscribe_confirm_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - //-------------------------------------------------------------------------- - MIH_C_Link_Primitive_Encode_Link_Event_Unsubscribe_confirm(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Configure_Thresholds_confirm(Bit_Buffer_t* bbP, MIH_C_Message_Link_Configure_Thresholds_confirm_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - //-------------------------------------------------------------------------- - MIH_C_Link_Primitive_Encode_Link_Configure_Thresholds_confirm(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Message_Encode_Get_Parameters_confirm(Bit_Buffer_t* bbP, MIH_C_Message_Link_Get_Parameters_confirm_t *messageP) -{ - //----------------------------------------------------------------------------- - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - BitBuffer_rewind(bbP); - bbP->m_byte_position = MSG_MIH_HEADER_SIZE_IN_BYTES; - - // TYPE - tlv = MIH_C_TLV_SOURCE_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->source); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - // TYPE - tlv = MIH_C_TLV_DESTINATION_MIHF_ID; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_MIHF_ID_encode(bbP, &messageP->destination); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - //-------------------------------------------------------------------------- - MIH_C_Link_Primitive_Encode_Link_Get_Parameters_confirm(bbP, &messageP->primitive); - - saved_byte_position = BitBuffer_getPosition(bbP); - bbP->m_byte_position = 0; - messageP->header.payload_length = saved_byte_position - MSG_MIH_HEADER_SIZE_IN_BYTES; - - - MIH_C_Link_Header_Encode(bbP, &messageP->header); - - bbP->m_byte_position = saved_byte_position; - - return saved_byte_position; -} diff --git a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_primitive_codec.c b/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_primitive_codec.c deleted file mode 100755 index 9ab37228c5..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/C/MIH_C_primitive_codec.c +++ /dev/null @@ -1,892 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MIH_C_INTERFACE -#define MIH_C_PRIMITIVE_CODEC_C -#include <assert.h> -#include "MIH_C_primitive_codec.h" - -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Decode_Link_Capability_Discover_request(Bit_Buffer_t* bbP, MIH_C_Link_Capability_Discover_request_t *primitiveP) -{ - //----------------------------------------------------------------------------- - return MIH_PRIMITIVE_DECODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Link_Capability_Discover_request2String(MIH_C_Link_Capability_Discover_request_t *primitiveP, char* bufP) -{ - //----------------------------------------------------------------------------- - return 0; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Decode_Link_Event_Subscribe_request(Bit_Buffer_t* bbP, MIH_C_Link_Event_Subscribe_request_t *primitiveP) -{ - //----------------------------------------------------------------------------- - - MIH_C_TLV_TYPE_T tlv; - u_int16_t length; - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - MIH_C_LINK_EVENT_LIST_decode(bbP, &primitiveP->RequestedLinkEventList); - -#if MIH_C_DEBUG_DESERIALIZATION - - if (primitiveP->RequestedLinkEventList & MIH_C_BIT_LINK_DETECTED) printf("SUBSCRIBE_REQUEST LINK_DETECTED\n"); - - if (primitiveP->RequestedLinkEventList & MIH_C_BIT_LINK_UP) printf("SUBSCRIBE_REQUEST LINK_UP\n"); - - if (primitiveP->RequestedLinkEventList & MIH_C_BIT_LINK_DOWN) printf("SUBSCRIBE_REQUEST LINK_DOWN\n"); - - if (primitiveP->RequestedLinkEventList & MIH_C_BIT_LINK_PARAMETERS_REPORT) printf("SUBSCRIBE_REQUEST LINK_PARAMETERS_REPORT\n"); - - if (primitiveP->RequestedLinkEventList & MIH_C_BIT_LINK_GOING_DOWN) printf("SUBSCRIBE_REQUEST LINK_GOING_DOWN\n"); - - if (primitiveP->RequestedLinkEventList & MIH_C_BIT_LINK_HANDOVER_IMMINENT) printf("SUBSCRIBE_REQUEST LINK_HANDOVER_IMMINENT\n"); - - if (primitiveP->RequestedLinkEventList & MIH_C_BIT_LINK_HANDOVER_COMPLETE) printf("SUBSCRIBE_REQUEST LINK_HANDOVER_COMPLETE\n"); - - if (primitiveP->RequestedLinkEventList & MIH_C_BIT_LINK_PDU_TRANSMIT_STATUS) printf("SUBSCRIBE_REQUEST LINK_PDU_TRANSMIT_STATUS\n"); - -#endif - - if (BitBuffer_isCheckReadOverflowOK(bbP, 0) == BIT_BUFFER_TRUE) { - return MIH_PRIMITIVE_DECODE_OK; - } else { - return MIH_PRIMITIVE_DECODE_TOO_SHORT; - } -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Link_Event_Subscribe_request2String(MIH_C_Link_Event_Subscribe_request_t *primitiveP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- PRIMITIVE Link_Event_Subscribe.request -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += MIH_C_LINK_EVENT_LIST2String(&primitiveP->RequestedLinkEventList, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - return buffer_index; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Decode_Link_Event_Unsubscribe_request(Bit_Buffer_t* bbP, MIH_C_Link_Event_Unsubscribe_request_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_EVENT_LIST_decode(bbP, &primitiveP->RequestedLinkEventList); - - if (BitBuffer_isCheckReadOverflowOK(bbP, 0) == BIT_BUFFER_TRUE) { - return MIH_PRIMITIVE_DECODE_OK; - } else { - return MIH_PRIMITIVE_DECODE_TOO_SHORT; - } -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Link_Event_Unsubscribe_request2String(MIH_C_Link_Event_Unsubscribe_request_t *primitiveP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- PRIMITIVE Link_Event_Unsubscribe.request -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += MIH_C_LINK_EVENT_LIST2String(&primitiveP->RequestedLinkEventList, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - return buffer_index; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Decode_Link_Get_Parameters_request(Bit_Buffer_t* bbP, MIH_C_Link_Get_Parameters_request_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - u_int16_t length; - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - assert(tlv == MIH_C_TLV_LINK_PARAM_TYPE_LIST); - MIH_C_LIST_LENGTH_decode(bbP, &length); - MIH_C_LINK_PARAM_TYPE_LIST_decode(bbP, &primitiveP->LinkParametersRequest_list); - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - assert(tlv == MIH_C_TLV_LINK_STATES_REQ); - MIH_C_LIST_LENGTH_decode(bbP, &length); - MIH_C_LINK_STATES_REQ_decode(bbP, &primitiveP->LinkStatesRequest); - - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - assert(tlv == MIH_C_TLV_LINK_DESC_REQ); - MIH_C_LIST_LENGTH_decode(bbP, &length); - MIH_C_LINK_DESC_REQ_decode(bbP, &primitiveP->LinkDescriptorsRequest); - - if (BitBuffer_isCheckReadOverflowOK(bbP, 0) == BIT_BUFFER_TRUE) { - return MIH_PRIMITIVE_DECODE_OK; - } else { - return MIH_PRIMITIVE_DECODE_TOO_SHORT; - } -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Link_Get_Parameters_request2String(MIH_C_Link_Get_Parameters_request_t *primitiveP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- PRIMITIVE Link_Get_Parameters.request -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "LINK_PARAM_TYPE_LIST = "); - buffer_index += MIH_C_LINK_PARAM_TYPE_LIST2String(&primitiveP->LinkParametersRequest_list, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nLINK_STATES_REQ = "); - buffer_index += MIH_C_LINK_STATES_REQ2String(&primitiveP->LinkStatesRequest, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nLINK_DESC_REQ = "); - buffer_index += MIH_C_LINK_DESC_REQ2String(&primitiveP->LinkDescriptorsRequest, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - return buffer_index; -} - -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Decode_Link_Configure_Thresholds_request(Bit_Buffer_t* bbP, MIH_C_Link_Configure_Thresholds_request_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - u_int16_t length; - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - MIH_C_LINK_CFG_PARAM_LIST_decode(bbP, &primitiveP->LinkConfigureParameterList_list); - - if (BitBuffer_isCheckReadOverflowOK(bbP, 0) == BIT_BUFFER_TRUE) { - return MIH_PRIMITIVE_DECODE_OK; - } else { - return MIH_PRIMITIVE_DECODE_TOO_SHORT; - } -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Link_Configure_Thresholds_request2String(MIH_C_Link_Configure_Thresholds_request_t *primitiveP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- PRIMITIVE Link_Configure_Threshold.request -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += MIH_C_LINK_CFG_PARAM_LIST2String(&primitiveP->LinkConfigureParameterList_list, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - return buffer_index; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Decode_Link_Action_request(Bit_Buffer_t* bbP, MIH_C_Link_Action_request_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_LINK_ADDR_T *PoALinkAddress = NULL; - MIH_C_TLV_TYPE_T tlv; - u_int16_t length; - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - assert(tlv == MIH_C_TLV_LINK_ACTION); - MIH_C_LIST_LENGTH_decode(bbP, &length); - - // Patch MW 03/05/2013 - if (length >2) { - MIH_C_LINK_ACTION_decode(bbP, &primitiveP->LinkAction); - } else { - MIH_C_LINK_ACTION_short_decode(bbP, &primitiveP->LinkAction) ; - } - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - assert(tlv == MIH_C_TLV_LINK_TIME_INTERVAL); - MIH_C_LIST_LENGTH_decode(bbP, &length); - MIH_C_UNSIGNED_INT2_decode(bbP, &primitiveP->ExecutionDelay); - - if (BitBuffer_isCheckReadOverflowOK(bbP, 0) == BIT_BUFFER_FALSE) { - return MIH_PRIMITIVE_DECODE_TOO_SHORT; - } - - MIH_C_TLV_TYPE_decode(bbP, &tlv); - - if (tlv == MIH_C_TLV_POA) { - PoALinkAddress = malloc(sizeof(MIH_C_LINK_ADDR_T)); - MIH_C_LINK_ADDR_decode(bbP, PoALinkAddress); - primitiveP->PoALinkAddress = PoALinkAddress; - } else { - primitiveP->PoALinkAddress = NULL; - } - - if (BitBuffer_isCheckReadOverflowOK(bbP, 0) == BIT_BUFFER_FALSE) { - free(PoALinkAddress); - return MIH_PRIMITIVE_DECODE_TOO_SHORT; - } - - return MIH_PRIMITIVE_DECODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Link_Action_request2String(MIH_C_Link_Action_request_t *primitiveP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- PRIMITIVE Link_Action.request -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += MIH_C_LINK_ACTION2String(&primitiveP->LinkAction, &bufP[buffer_index]); - buffer_index += MIH_C_UNSIGNED_INT22String(&primitiveP->ExecutionDelay, &bufP[buffer_index]); - - if (primitiveP->PoALinkAddress != NULL) { - buffer_index += MIH_C_LINK_ADDR2String(primitiveP->PoALinkAddress, &bufP[buffer_index]); - } - - buffer_index += sprintf(&bufP[buffer_index], "\n"); - return buffer_index; -} -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Register_indication(Bit_Buffer_t* bbP, MIH_C_Link_Register_indication_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - u_int16_t encode_length; - - // TYPE - tlv = MIH_C_TLV_LINK_INTERFACE_TYPE_ADDR; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_ID_encode(bbP, &primitiveP->Link_Id); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - return MIH_PRIMITIVE_ENCODE_OK; -} -#endif -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Link_Register_indication2String(MIH_C_Link_Register_indication_t *primitiveP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- PRIMITIVE Link_Register.indication -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += MIH_C_LINK_ID2String(&primitiveP->Link_Id, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - return buffer_index; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Detected_indication(Bit_Buffer_t* bbP, MIH_C_Link_Detected_indication_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - u_int16_t encode_length; - - // TYPE - tlv = MIH_C_TLV_LINK_DET_INFO; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_DET_INFO_encode(bbP, &primitiveP->LinkDetectedInfo); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - return MIH_PRIMITIVE_ENCODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Up_indication(Bit_Buffer_t* bbP, MIH_C_Link_Up_indication_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - u_int16_t encode_length; - - // TYPE - tlv = MIH_C_TLV_LINK_IDENTIFIER; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_TUPLE_ID_encode(bbP, &primitiveP->LinkIdentifier); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - if (primitiveP->OldAccessRouter) { - // TYPE - tlv = MIH_C_TLV_OLD_ACCESS_ROUTER; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_ADDR_encode(bbP, primitiveP->OldAccessRouter); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - } - - if (primitiveP->NewAccessRouter) { - // TYPE - tlv = MIH_C_TLV_NEW_ACCESS_ROUTER; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_ADDR_encode(bbP, primitiveP->NewAccessRouter); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - } - - if (primitiveP->IPRenewalFlag) { - // TYPE - tlv = MIH_C_TLV_IP_RENEWAL_FLAG; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_IP_RENEWAL_FLAG_encode(bbP, primitiveP->IPRenewalFlag); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - } - - if (primitiveP->MobilityManagementSupport) { - // TYPE - tlv = MIH_C_TLV_MOBILITY_MANAGEMENT_SUPPORT; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_IP_MOB_MGMT_encode(bbP, primitiveP->MobilityManagementSupport); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - } - - return MIH_PRIMITIVE_ENCODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Parameters_Report_indication(Bit_Buffer_t* bbP, MIH_C_Link_Parameters_Report_indication_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - u_int16_t encode_length; - - - // ------- LinkIdentifier-------- - // TYPE - tlv = MIH_C_TLV_LINK_IDENTIFIER; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_TUPLE_ID_encode(bbP, &primitiveP->LinkIdentifier); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - // ------- LinkParametersReportList_list-------- - // TYPE - tlv = MIH_C_TLV_LINK_PARAMETER_REPORT_LIST; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_PARAM_RPT_LIST_encode(bbP, &primitiveP->LinkParametersReportList_list); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - return MIH_PRIMITIVE_ENCODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Going_Down_indication(Bit_Buffer_t* bbP, MIH_C_Link_Going_Down_indication_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - u_int16_t encode_length; - - // ------- LinkIdentifier-------- - // TYPE - tlv = MIH_C_TLV_LINK_IDENTIFIER; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_TUPLE_ID_encode(bbP, &primitiveP->LinkIdentifier); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - // ------- TimeInterval-------- - // TYPE - tlv = MIH_C_TLV_LINK_TIME_INTERVAL; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - MIH_C_LIST_LENGTH_encode(bbP, sizeof(MIH_C_UNSIGNED_INT2_T)); - // VALUE - MIH_C_UNSIGNED_INT2_encode(bbP, &primitiveP->TimeInterval); - - // ------- LinkGoingDownReason-------- - // TYPE - tlv = MIH_C_TLV_LINK_GOING_DOWN_REASON_CODE; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - MIH_C_LIST_LENGTH_encode(bbP, sizeof(MIH_C_LINK_GD_REASON_T)); - // VALUE - MIH_C_LINK_GD_REASON_encode(bbP, &primitiveP->LinkGoingDownReason); - - return MIH_PRIMITIVE_ENCODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Down_indication(Bit_Buffer_t* bbP, MIH_C_Link_Down_indication_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - u_int16_t encode_length; - - // ------- LinkIdentifier-------- - // TYPE - tlv = MIH_C_TLV_LINK_IDENTIFIER; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_TUPLE_ID_encode(bbP, &primitiveP->LinkIdentifier); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - // ------- OldAccessRouter-------- - if (primitiveP->OldAccessRouter != NULL) { - // TYPE - tlv = MIH_C_TLV_OLD_ACCESS_ROUTER; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_ADDR_encode(bbP, primitiveP->OldAccessRouter); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - } - - // ------- ReasonCode-------- - // TYPE - tlv = MIH_C_TLV_LINK_DOWN_REASON_CODE; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - - MIH_C_LIST_LENGTH_encode(bbP, sizeof(MIH_C_LINK_DN_REASON_T)); - // VALUE - MIH_C_LINK_DN_REASON_encode(bbP, &primitiveP->ReasonCode); - - return MIH_PRIMITIVE_ENCODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Capability_Discover_confirm(Bit_Buffer_t* bbP, MIH_C_Link_Capability_Discover_confirm_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - //--------- Status ------------ - // TYPE - tlv = MIH_C_TLV_STATUS; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // LENGTH - encode_length = sizeof(MIH_C_STATUS_T); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - // VALUE - MIH_C_STATUS_encode(bbP, &primitiveP->Status); - - - //--------- SupportedLinkEventList ------------ - if (primitiveP->SupportedLinkEventList != NULL) { - // TYPE - tlv = MIH_C_TLV_LINK_EVENT_LIST; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // LENGTH - encode_length = sizeof(MIH_C_LINK_EVENT_LIST_T); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - // VALUE - MIH_C_LINK_EVENT_LIST_encode(bbP, primitiveP->SupportedLinkEventList); - } - - - //--------- SupportedLinkCommandList ------------ - if (primitiveP->SupportedLinkCommandList != NULL) { - // TYPE - tlv = MIH_C_TLV_LINK_CMD_LIST; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // LENGTH - encode_length = sizeof(MIH_C_LINK_CMD_LIST_T); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - // VALUE - MIH_C_LINK_CMD_LIST_encode(bbP, primitiveP->SupportedLinkCommandList); - } - - return MIH_PRIMITIVE_ENCODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Link_Capability_Discover_confirm2String(MIH_C_Link_Capability_Discover_confirm_t *primitiveP, char* bufP) -{ - //----------------------------------------------------------------------------- - - unsigned int buffer_index = 0; - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "- PRIMITIVE Capability_Discover.confirm -\n"); - buffer_index += sprintf(&bufP[buffer_index], "--------------------------------------------------\n"); - buffer_index += sprintf(&bufP[buffer_index], "STATUS = "); - buffer_index += MIH_C_STATUS2String(&primitiveP->Status, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nLINK_EVENT_LIST = "); - buffer_index += MIH_C_LINK_EVENT_LIST2String(primitiveP->SupportedLinkEventList, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\nLINK_CMD_LIST = "); - buffer_index += MIH_C_LINK_CMD_LIST2String(primitiveP->SupportedLinkEventList, &bufP[buffer_index]); - buffer_index += sprintf(&bufP[buffer_index], "\n"); - return buffer_index; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Event_Subscribe_confirm(Bit_Buffer_t* bbP, MIH_C_Link_Event_Subscribe_confirm_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - //--------- Status ------------ - // TYPE - tlv = MIH_C_TLV_STATUS; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // LENGTH - encode_length = sizeof(MIH_C_STATUS_T); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - // VALUE - MIH_C_STATUS_encode(bbP, &primitiveP->Status); - - - //--------- SupportedLinkEventList ------------ - if (primitiveP->ResponseLinkEventList != NULL) { - // TYPE - tlv = MIH_C_TLV_LINK_EVENT_LIST; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // LENGTH - // Bitmap - encode_length = sizeof(MIH_C_LINK_EVENT_LIST_T); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - // VALUE - MIH_C_LINK_EVENT_LIST_encode(bbP, primitiveP->ResponseLinkEventList); - } - - return MIH_PRIMITIVE_ENCODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Event_Unsubscribe_confirm(Bit_Buffer_t* bbP, MIH_C_Link_Event_Unsubscribe_confirm_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - //--------- Status ------------ - // TYPE - tlv = MIH_C_TLV_STATUS; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // LENGTH - encode_length = sizeof(MIH_C_STATUS_T); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - // VALUE - MIH_C_STATUS_encode(bbP, &primitiveP->Status); - - - //--------- SupportedLinkEventList ------------ - if (primitiveP->ResponseLinkEventList != NULL) { - // TYPE - tlv = MIH_C_TLV_LINK_EVENT_LIST; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // LENGTH - // Bitmap - encode_length = sizeof(MIH_C_LINK_EVENT_LIST_T); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - // VALUE - MIH_C_LINK_EVENT_LIST_encode(bbP, primitiveP->ResponseLinkEventList); - } - - return MIH_PRIMITIVE_ENCODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Configure_Thresholds_confirm(Bit_Buffer_t* bbP, MIH_C_Link_Configure_Thresholds_confirm_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - u_int16_t encode_length; - - //--------- Status ------------ - // TYPE - tlv = MIH_C_TLV_STATUS; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // LENGTH - encode_length = sizeof(MIH_C_STATUS_T); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - // VALUE - MIH_C_STATUS_encode(bbP, &primitiveP->Status); - - - //--------- SupportedLinkEventList ------------ - if (primitiveP->LinkConfigureStatusList_list != NULL) { - // TYPE - tlv = MIH_C_TLV_CONFIGURE_RESPONSE_LIST; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // LENGTH - encode_length = sizeof(MIH_C_LINK_CFG_STATUS_T) * primitiveP->LinkConfigureStatusList_list->length; - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - // VALUE - MIH_C_LINK_CFG_STATUS_LIST_encode(bbP, primitiveP->LinkConfigureStatusList_list); - } - - return MIH_PRIMITIVE_ENCODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Get_Parameters_confirm(Bit_Buffer_t* bbP, MIH_C_Link_Get_Parameters_confirm_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - u_int16_t encode_length; - - //--------- Status ------------ - // TYPE - tlv = MIH_C_TLV_STATUS; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // LENGTH - encode_length = sizeof(MIH_C_STATUS_T); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - // VALUE - MIH_C_STATUS_encode(bbP, &primitiveP->Status); - - //--------- LinkParametersStatusList_list ------------ - // TYPE - tlv = MIH_C_TLV_LINK_PARAMETERS_STATUS_LIST; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_PARAM_LIST_encode(bbP, primitiveP->LinkParametersStatusList_list); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH (BECAUSE LinkParametersStatusList_list contains a list) - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - //--------- LinkStatesResponse_list ------------ - // TYPE - tlv = MIH_C_TLV_LINK_STATES_RSP_LIST; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_STATES_RSP_LIST_encode(bbP, primitiveP->LinkStatesResponse_list); - end_byte_position = BitBuffer_getPosition(bbP); - // LENGTH (DONE AFTER BECAUSE CONTAINS CHOICES OF NOT EQUAL SIZES) - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - //--------- LinkDescriptorsResponse_list ------------ - // TYPE - tlv = MIH_C_TLV_LINK_DESC_RSP_LIST; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_DESC_RSP_LIST_encode(bbP, primitiveP->LinkDescriptorsResponse_list); - end_byte_position = BitBuffer_getPosition(bbP); - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - - - return MIH_PRIMITIVE_ENCODE_OK; -} -//----------------------------------------------------------------------------- -int MIH_C_Link_Primitive_Encode_Link_Action_confirm(Bit_Buffer_t* bbP, MIH_C_Link_Action_confirm_t *primitiveP) -{ - //----------------------------------------------------------------------------- - MIH_C_TLV_TYPE_T tlv; - unsigned int saved_byte_position; - unsigned int end_byte_position; - unsigned int hole_size; - u_int16_t encode_length; - - //--------- Status ------------ - // TYPE - tlv = MIH_C_TLV_STATUS; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // LENGTH - encode_length = sizeof(MIH_C_STATUS_T); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - // VALUE - MIH_C_STATUS_encode(bbP, &primitiveP->Status); - - if (primitiveP->Status == MIH_C_STATUS_SUCCESS) { - if (primitiveP->ScanResponseSet_list != NULL) { - //--------- ScanResponseSet_list ------------ - // TYPE - tlv = MIH_C_TLV_LINK_SCAN_RSP_LIST; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_SCAN_RSP_LIST_encode(bbP, primitiveP->ScanResponseSet_list); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - } - - //--------- LinkActionResult ------------ - // TYPE - tlv = MIH_C_TLV_LINK_AC_RESULT; - MIH_C_TLV_TYPE_encode(bbP, &tlv); - // VALUE - saved_byte_position = BitBuffer_getPosition(bbP); - MIH_C_LINK_AC_RESULT_encode(bbP, primitiveP->LinkActionResult); - end_byte_position = BitBuffer_getPosition(bbP); - - // LENGTH - encode_length = end_byte_position - saved_byte_position; - hole_size = MIH_C_LIST_LENGTH_get_encode_num_bytes(encode_length); - BitBuffer_write_shift_last_n_bytes_right(bbP, encode_length, hole_size); - BitBuffer_rewind_to(bbP, saved_byte_position); - MIH_C_LIST_LENGTH_encode(bbP, encode_length); - BitBuffer_rewind_to(bbP, end_byte_position + hole_size); - } - - return MIH_PRIMITIVE_ENCODE_OK; -} diff --git a/openair3/RAL-LTE/INTERFACE-802.21/DOXYGEN/Doxyfile b/openair3/RAL-LTE/INTERFACE-802.21/DOXYGEN/Doxyfile deleted file mode 100755 index 65e2c92f34..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/DOXYGEN/Doxyfile +++ /dev/null @@ -1,1554 +0,0 @@ -# Doxyfile 1.6.3 - -# 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 = MIH-C - -# 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 = V0.1 - -# 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 = ./html - -# 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, Esperanto, 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, Serbian-Cyrilic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -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 = NO - -# 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 = NO - -# 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 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 - -# Doxygen selects the parser to use depending on the extension of the files it parses. -# With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this tag. -# The format is ext=language, where ext is a file extension, and language is one of -# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, -# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# 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 = NO - -# 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 - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# 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 = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# 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 FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# 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_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = 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 = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# 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 = ./.. - -# 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 = *.h \ - RECURSIVE \ - = \ - NO - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. 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 = images/ - -# 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 = YES - -# 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 = YES - -# 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 documentation. - -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 = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = footer.html - -# 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_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# 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 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_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. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. - -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 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_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 - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. -# For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see -# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's -# filter section matches. -# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# 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 YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = YES - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# 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 - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = NO - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# 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. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# 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 - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = 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. -#LG WAS NO -MACRO_EXPANSION = YES - -# 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. -#LG WAS NO -EXPAND_ONLY_PREDEF = YES - -# 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 = MIH_C_MEDIEVAL_EXTENSIONS=1 MIH_C_F1_BASIC_DATA_TYPES_CODEC_C=1 MIH_C_F2_GENERAL_DATA_TYPES_CODEC_C=1 MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC_C=1 MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC_C=1 MIH_C_F9_DATA_TYPES_FOR_QOS_CODEC_C=1 MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS_C=1 - -# 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 = private_F1_codec protected_F1_codec public_F1_codec private_F2_codec protected_F2_codec public_F2_codec private_F3_codec protected_F3_codec public_F3_codec private_F4_codec protected_F4_codec public_F4_codec private_F9_codec protected_F9_codec public_F9_codec public_L2_codec protected_L2_codec private_L2_codec private_Medieval_extensions protected_Medieval_extensions public_Medieval_extensions private_bit_buffer protected_bit_buffer public_bit_buffer private_header_codec protected_header_codec public_header_codec private_mih_c_log protected_mih_c_log public_mih_c_log private_mih_c_msg_codec protected_mih_c_msg_codec public_mih_c_msg_codec private_mih_c_primitive_codec protected_mih_c_primitive_codec public_mih_c_primitive_codec - -# 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 = YES - -# 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 = NO - -# 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 - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# 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 = NO - -# 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 = /usr/bin/dot - -# 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 disabled by default, because dot on Windows does not -# seem to support this out of the box. 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 = NO - -# 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 diff --git a/openair3/RAL-LTE/INTERFACE-802.21/DOXYGEN/footer.html b/openair3/RAL-LTE/INTERFACE-802.21/DOXYGEN/footer.html deleted file mode 100755 index b5b833a2dd..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/DOXYGEN/footer.html +++ /dev/null @@ -1,16 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<!-- -<html xml:lang="en"> -<head> -<title> </title> -</head> - -<body>--> - - -<DIV ALIGN=CENTER> -<img alt="EURECOM - PMIP6D" src="http://mmsp01.eurecom.fr/EURECOM_logo.gif" height="90" width="270" /> -</DIV> -</body> - -</html> diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C.h deleted file mode 100755 index cc0a036016..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C.h +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C.h - * \brief This file must be the only file to be included in code dealing with the MIH_C interface. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MIH_C_H__ -# define __MIH_C_H__ -#include "MIH_C_bit_buffer.h" -#include "UTIL/LOG/log.h" -#include "MIH_C_Link_Constants.h" -#include "MIH_C_Types.h" -#include "MIH_C_header_codec.h" -#include "MIH_C_F1_basic_data_types_codec.h" -#include "MIH_C_F2_general_data_types_codec.h" -#include "MIH_C_F3_data_types_for_address_codec.h" -#include "MIH_C_F4_data_types_for_links_codec.h" -#include "MIH_C_F9_data_types_for_qos_codec.h" -#include "MIH_C_F13_data_types_for_information_elements_codec.h" -#include "MIH_C_L2_type_values_for_tlv_encoding.h" -#include "MIH_C_Medieval_extensions.h" -#include "MIH_C_Link_Primitives.h" -#include "MIH_C_Link_Messages.h" -#include "MIH_C_primitive_codec.h" -#include "MIH_C_msg_codec.h" - -void MIH_C_init(void); -void MIH_C_exit(void); - -#define DEBUG_TRACE_DETAILS -#endif diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F13_data_types_for_information_elements_codec.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F13_data_types_for_information_elements_codec.h deleted file mode 100755 index a0e4ba8772..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F13_data_types_for_information_elements_codec.h +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_F13_data_types_for_information_elements_codec.h - * \brief This file defines the prototypes of the functions for coding and decoding Data type for information elements defined in Std 802.21-2008 Table F13. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ -/** \defgroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS F13 Data types for information elements - * \ingroup MIH_C_INTERFACE - * - * @{ - */ - -#ifndef __MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS_H__ -# define __MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS_C -# define private_F13_codec(x) x -# define protected_F13_codec(x) x -# define public_F13_codec(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_F13_codec(x) -# define protected_F13_codec(x) extern x -# define public_F13_codec(x) extern x -# else -# define private_F13_codec(x) -# define protected_F13_codec(x) -# define public_F13_codec(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- - -#endif -/** @}*/ diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F1_basic_data_types_codec.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F1_basic_data_types_codec.h deleted file mode 100755 index 6b6dfdb4b6..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F1_basic_data_types_codec.h +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_F1_basic_data_types_codec.h - * \brief This file defines the prototypes of the functions for coding and decoding basic data types defined in Std 802.21-2008 Table F1. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ -/** \defgroup MIH_C_F1_BASIC_DATA_TYPES F1 Basic data types codec - * \ingroup MIH_C_INTERFACE - * - * @{ - */ - -#ifndef __MIH_C_F1_BASIC_DATA_TYPES_CODEC_H__ -# define __MIH_C_F1_BASIC_DATA_TYPES_CODEC_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_F1_BASIC_DATA_TYPES_CODEC_C -# define private_F1_codec(x) x -# define protected_F1_codec(x) x -# define public_F1_codec(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_F1_codec(x) -# define protected_F1_codec(x) extern x -# define public_F1_codec(x) extern x -# else -# define private_F1_codec(x) -# define protected_F1_codec(x) -# define public_F1_codec(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -typedef struct MIH_C_F1_Generic_List { - u_int16_t length; - u_int8_t val[2]; -} MIH_C_F1_Generic_List_t; -//----------------------------------------------------------------------------- -typedef struct MIH_C_F1_Generic_Octet { - u_int8_t val[2]; -} MIH_C_F1_Generic_Octet_t; -//----------------------------------------------------------------------------- -public_F1_codec( void MIH_C_BITMAP8_encode (Bit_Buffer_t* bbP, MIH_C_BITMAP8_T* dataP);) -public_F1_codec( void MIH_C_BITMAP16_encode (Bit_Buffer_t* bbP, MIH_C_BITMAP16_T* dataP);) -public_F1_codec( void MIH_C_BITMAP24_encode (Bit_Buffer_t* bbP, MIH_C_BITMAP24_T* dataP);) -public_F1_codec( void MIH_C_BITMAP32_encode (Bit_Buffer_t* bbP, MIH_C_BITMAP32_T* dataP);) -public_F1_codec( void MIH_C_BITMAP64_encode (Bit_Buffer_t* bbP, MIH_C_BITMAP64_T* dataP);) -public_F1_codec( void MIH_C_BITMAP128_encode (Bit_Buffer_t* bbP, MIH_C_BITMAP128_T* dataP);) -public_F1_codec( void MIH_C_BITMAP256_encode (Bit_Buffer_t* bbP, MIH_C_BITMAP256_T* dataP);) -public_F1_codec( void MIH_C_CHOICE_encode (Bit_Buffer_t* bbP, MIH_C_CHOICE_T* dataP);) -public_F1_codec( void MIH_C_INTEGER1_encode (Bit_Buffer_t* bbP, MIH_C_INTEGER1_T* dataP);) -public_F1_codec( void MIH_C_INTEGER2_encode (Bit_Buffer_t* bbP, MIH_C_INTEGER2_T* dataP);) -public_F1_codec( void MIH_C_INTEGER4_encode (Bit_Buffer_t* bbP, MIH_C_INTEGER4_T* dataP);) -public_F1_codec( void MIH_C_INTEGER8_encode (Bit_Buffer_t* bbP, MIH_C_INTEGER8_T* dataP);) -public_F1_codec( void MIH_C_NULL_encode (Bit_Buffer_t* bbP, MIH_C_NULL_T* dataP);) -public_F1_codec( void MIH_C_OCTET_encode (Bit_Buffer_t* bbP, MIH_C_F1_Generic_Octet_t *dataP, int lengthP);) -public_F1_codec( void MIH_C_UNSIGNED_INT1_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT1_T* dataP);) -public_F1_codec( void MIH_C_UNSIGNED_INT2_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT2_T* dataP);) -public_F1_codec( void MIH_C_UNSIGNED_INT4_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT4_T* dataP);) -public_F1_codec( void MIH_C_UNSIGNED_INT8_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT8_T* dataP);) -public_F1_codec( void MIH_C_LIST_LENGTH_encode (Bit_Buffer_t* bbP, u_int16_t lengthP);) -//----------------------------------------------------------------------------- -public_F1_codec( void MIH_C_BITMAP8_decode (Bit_Buffer_t* bbP, MIH_C_BITMAP8_T* dataP);) -public_F1_codec( void MIH_C_BITMAP16_decode (Bit_Buffer_t* bbP, MIH_C_BITMAP16_T* dataP);) -public_F1_codec( void MIH_C_BITMAP24_decode (Bit_Buffer_t* bbP, MIH_C_BITMAP24_T* dataP);) -public_F1_codec( void MIH_C_BITMAP32_decode (Bit_Buffer_t* bbP, MIH_C_BITMAP32_T* dataP);) -public_F1_codec( void MIH_C_BITMAP64_decode (Bit_Buffer_t* bbP, MIH_C_BITMAP64_T* dataP);) -public_F1_codec( void MIH_C_BITMAP128_decode (Bit_Buffer_t* bbP, MIH_C_BITMAP128_T* dataP);) -public_F1_codec( void MIH_C_BITMAP256_decode (Bit_Buffer_t* bbP, MIH_C_BITMAP256_T* dataP);) -public_F1_codec( void MIH_C_CHOICE_decode (Bit_Buffer_t* bbP, MIH_C_CHOICE_T* dataP);) -public_F1_codec( void MIH_C_INTEGER1_decode (Bit_Buffer_t* bbP, MIH_C_INTEGER1_T* dataP);) -public_F1_codec( void MIH_C_INTEGER2_decode (Bit_Buffer_t* bbP, MIH_C_INTEGER2_T* dataP);) -public_F1_codec( void MIH_C_INTEGER4_decode (Bit_Buffer_t* bbP, MIH_C_INTEGER4_T* dataP);) -public_F1_codec( void MIH_C_INTEGER8_decode (Bit_Buffer_t* bbP, MIH_C_INTEGER8_T* dataP);) -public_F1_codec( void MIH_C_NULL_decode (Bit_Buffer_t* bbP);) -public_F1_codec( void MIH_C_OCTET_decode (Bit_Buffer_t* bbP, MIH_C_F1_Generic_Octet_t *dataP, int lengthP);) -public_F1_codec( void MIH_C_UNSIGNED_INT1_decode (Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT1_T* dataP);) -public_F1_codec( void MIH_C_UNSIGNED_INT2_decode (Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT2_T* dataP);) -public_F1_codec( void MIH_C_UNSIGNED_INT4_decode (Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT4_T* dataP);) -public_F1_codec( void MIH_C_UNSIGNED_INT8_decode (Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT8_T* dataP);) -public_F1_codec( void MIH_C_LIST_LENGTH_decode (Bit_Buffer_t* bbP, u_int16_t *lengthP);) -//----------------------------------------------------------------------------- -public_F1_codec( unsigned int MIH_C_BITMAP82String(MIH_C_BITMAP8_T* dataP, char* bufP);) -public_F1_codec( unsigned int MIH_C_BITMAP162String(MIH_C_BITMAP16_T* dataP, char* bufP);) -public_F1_codec( unsigned int MIH_C_BITMAP242String(MIH_C_BITMAP24_T* dataP, char* bufP);) -public_F1_codec( unsigned int MIH_C_UNSIGNED_INT12String(MIH_C_UNSIGNED_INT1_T* dataP, char* bufP);) -public_F1_codec( unsigned int MIH_C_UNSIGNED_INT22String(MIH_C_UNSIGNED_INT2_T* dataP, char* bufP);) -public_F1_codec( unsigned int MIH_C_UNSIGNED_INT42String(MIH_C_UNSIGNED_INT4_T* dataP, char* bufP);) -public_F1_codec( unsigned int MIH_C_UNSIGNED_INT82String(MIH_C_UNSIGNED_INT8_T* dataP, char* bufP);) -//----------------------------------------------------------------------------- -public_F1_codec(u_int16_t MIH_C_LIST_LENGTH_get_encode_num_bytes(u_int16_t lengthP);) - -#endif -/** @}*/ diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F2_general_data_types_codec.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F2_general_data_types_codec.h deleted file mode 100755 index 1f9a6504f5..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F2_general_data_types_codec.h +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_F2_general_data_types_codec.h - * \brief This file defines the prototypes of the functions for coding and decoding general data types defined in Std 802.21-2008 Table F2. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ -/** \defgroup MIH_C_F2_GENERAL_DATA_TYPES_CODEC F2 General data types codec - * \ingroup MIH_C_INTERFACE - * - * @{ - */ - -#ifndef __MIH_C_F2_GENERAL_DATA_TYPES_CODEC_H__ -# define __MIH_C_F2_GENERAL_DATA_TYPES_CODEC_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_F2_GENERAL_DATA_TYPES_CODEC_C -# define private_F2_codec(x) x -# define protected_F2_codec(x) x -# define public_F2_codec(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_F2_codec(x) -# define protected_F2_codec(x) extern x -# define public_F2_codec(x) extern x -# else -# define private_F2_codec(x) -# define protected_F2_codec(x) -# define public_F2_codec(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -public_F2_codec( unsigned int MIH_C_BOOLEAN2String(MIH_C_BOOLEAN_T* dataP, char* bufP);) -public_F2_codec( unsigned int MIH_C_STATUS2String(MIH_C_STATUS_T *statusP, char* bufP);) - -#endif -/** @}*/ diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F3_data_types_for_address_codec.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F3_data_types_for_address_codec.h deleted file mode 100755 index 1e8749e670..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F3_data_types_for_address_codec.h +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_F3_data_types_for_address_codec.h - * \brief This file defines the prototypes of the functions for coding and decoding data types for addresses defined in Std 802.21-2008 Table F3. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ -/** \defgroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC F3 Data types for address codec - * \ingroup MIH_C_INTERFACE - * - * @{ - */ - -#ifndef __MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC_H__ -# define __MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC_C -# define private_F3_codec(x) x -# define protected_F3_codec(x) x -# define public_F3_codec(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_F3_codec(x) -# define protected_F3_codec(x) extern x -# define public_F3_codec(x) extern x -# else -# define private_F3_codec(x) -# define protected_F3_codec(x) -# define public_F3_codec(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -public_F3_codec(unsigned int MIH_C_3GPP_2G_CELL_ID2String(MIH_C_3GPP_2G_CELL_ID_T *dataP, char* bufP);) -public_F3_codec(void MIH_C_3GPP_2G_CELL_ID_encode (Bit_Buffer_t* bbP, MIH_C_3GPP_2G_CELL_ID_T *dataP);) -public_F3_codec(void MIH_C_3GPP_2G_CELL_ID_decode (Bit_Buffer_t* bbP, MIH_C_3GPP_2G_CELL_ID_T *dataP);) -public_F3_codec(unsigned int MIH_C_3GPP_3G_CELL_ID2String(MIH_C_3GPP_3G_CELL_ID_T *dataP, char* bufP);) -public_F3_codec(void MIH_C_3GPP_3G_CELL_ID_encode (Bit_Buffer_t* bbP, MIH_C_3GPP_3G_CELL_ID_T *dataP);) -public_F3_codec(void MIH_C_3GPP_3G_CELL_ID_decode (Bit_Buffer_t* bbP, MIH_C_3GPP_3G_CELL_ID_T *dataP);) -public_F3_codec(unsigned int MIH_C_LINK_ADDR2String(MIH_C_LINK_ADDR_T *dataP, char* bufP);) -public_F3_codec(void MIH_C_LINK_ADDR_encode (Bit_Buffer_t* bbP, MIH_C_LINK_ADDR_T *dataP);) -public_F3_codec(void MIH_C_LINK_ADDR_decode (Bit_Buffer_t* bbP, MIH_C_LINK_ADDR_T *dataP);) -#endif -/** @}*/ diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F4_data_types_for_links_codec.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F4_data_types_for_links_codec.h deleted file mode 100755 index 4bf840d818..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F4_data_types_for_links_codec.h +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_F4_data_types_for_links_codec.h - * \brief This file defines the prototypes of the functions for coding and decoding data types for links defined in Std 802.21-2008 Table F4. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ -/** \defgroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC F4 Data types for links codec - * \ingroup MIH_C_INTERFACE - * - * @{ - */ - -#ifndef __MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC_H__ -# define __MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC_C -# define private_F4_codec(x) x -# define protected_F4_codec(x) x -# define public_F4_codec(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_F4_codec(x) -# define protected_F4_codec(x) extern x -# define public_F4_codec(x) extern x -# else -# define private_F4_codec(x) -# define protected_F4_codec(x) -# define public_F4_codec(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -public_F4_codec(unsigned int MIH_C_OPMODE2String2(MIH_C_OPMODE_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_DEV_STATE_RSP_encode(Bit_Buffer_t* bbP, MIH_C_DEV_STATE_RSP_T *dataP);) -public_F4_codec(void MIH_C_DEV_STATE_RSP_decode(Bit_Buffer_t* bbP, MIH_C_DEV_STATE_RSP_T *dataP);) -public_F4_codec(unsigned int MIH_C_LINK_EVENT_LIST2String2(MIH_C_LINK_EVENT_LIST_T *dataP, char* bufP);) -public_F4_codec(unsigned int MIH_C_LINK_CMD_LIST2String2(MIH_C_LINK_CMD_LIST_T *dataP, char* bufP);) -public_F4_codec(unsigned int MIH_C_LINK_TYPE2String2(MIH_C_LINK_TYPE_T *dataP, char* bufP);) -public_F4_codec(unsigned int MIH_C_LINK_ID2String(MIH_C_LINK_ID_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_LINK_ID_encode(Bit_Buffer_t* bbP, MIH_C_LINK_ID_T *dataP);) -public_F4_codec(void MIH_C_LINK_ID_decode(Bit_Buffer_t* bbP, MIH_C_LINK_ID_T *dataP);) -public_F4_codec(void MIH_C_LINK_ACTION_REQ_encode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_REQ_T *dataP);) -public_F4_codec(void MIH_C_LINK_ACTION_REQ_decode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_REQ_T *dataP);) -public_F4_codec(unsigned int MIH_C_SIG_STRENGTH2String(MIH_C_SIG_STRENGTH_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_SIG_STRENGTH_encode(Bit_Buffer_t* bbP, MIH_C_SIG_STRENGTH_T *dataP);) -public_F4_codec(void MIH_C_SIG_STRENGTH_decode(Bit_Buffer_t* bbP, MIH_C_SIG_STRENGTH_T *dataP);) -public_F4_codec(unsigned int MIH_C_LINK_SCAN_RSP2String(MIH_C_LINK_SCAN_RSP_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_LINK_SCAN_RSP_encode(Bit_Buffer_t* bbP, MIH_C_LINK_SCAN_RSP_T *dataP);) -public_F4_codec(void MIH_C_LINK_SCAN_RSP_decode(Bit_Buffer_t* bbP, MIH_C_LINK_SCAN_RSP_T *dataP);) -public_F4_codec(void MIH_C_LINK_ACTION_RSP_encode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_RSP_T *dataP);) -public_F4_codec(void MIH_C_LINK_ACTION_RSP_decode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_RSP_T *dataP);) -public_F4_codec(unsigned int MIH_C_THRESHOLD2String(MIH_C_THRESHOLD_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_THRESHOLD_encode(Bit_Buffer_t* bbP, MIH_C_THRESHOLD_T *dataP);) -public_F4_codec(void MIH_C_THRESHOLD_decode(Bit_Buffer_t* bbP, MIH_C_THRESHOLD_T *dataP);) -public_F4_codec(unsigned int MIH_C_LINK_PARAM_TYPE2String( MIH_C_LINK_PARAM_TYPE_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_LINK_PARAM_TYPE_encode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_TYPE_T *dataP);) -public_F4_codec(void MIH_C_LINK_PARAM_TYPE_decode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_TYPE_T *dataP);) -public_F4_codec(unsigned int MIH_C_LINK_CFG_PARAM2String(MIH_C_LINK_CFG_PARAM_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_LINK_CFG_PARAM_encode(Bit_Buffer_t* bbP, MIH_C_LINK_CFG_PARAM_T *dataP);) -public_F4_codec(void MIH_C_LINK_CFG_PARAM_decode(Bit_Buffer_t* bbP, MIH_C_LINK_CFG_PARAM_T *dataP);) -public_F4_codec(unsigned int MIH_C_LINK_CFG_STATUS2String(MIH_C_LINK_CFG_STATUS_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_LINK_CFG_STATUS_encode(Bit_Buffer_t* bbP, MIH_C_LINK_CFG_STATUS_T *dataP);) -public_F4_codec(void MIH_C_LINK_CFG_STATUS_decode(Bit_Buffer_t* bbP, MIH_C_LINK_CFG_STATUS_T *dataP);) -public_F4_codec(unsigned int MIH_C_LINK_DESC_RSP2String(MIH_C_LINK_DESC_RSP_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_LINK_DESC_RSP_encode(Bit_Buffer_t* bbP, MIH_C_LINK_DESC_RSP_T *dataP);) -public_F4_codec(void MIH_C_LINK_DESC_RSP_decode(Bit_Buffer_t* bbP, MIH_C_LINK_DESC_RSP_T *dataP);) -public_F4_codec(unsigned int MIH_C_LINK_PARAM2String(MIH_C_LINK_PARAM_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_LINK_PARAM_encode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_T *dataP);) -public_F4_codec(void MIH_C_LINK_PARAM_decode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_T *dataP);) -public_F4_codec(unsigned int MIH_C_LINK_PARAM_RPT2String(MIH_C_LINK_PARAM_RPT_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_LINK_PARAM_RPT_encode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_RPT_T *dataP);) -public_F4_codec(void MIH_C_LINK_PARAM_RPT_decode(Bit_Buffer_t* bbP, MIH_C_LINK_PARAM_RPT_T *dataP);) -public_F4_codec(void MIH_C_LINK_POA_LIST_encode(Bit_Buffer_t* bbP, MIH_C_LINK_POA_LIST_T *dataP);) -public_F4_codec(void MIH_C_LINK_POA_LIST_decode(Bit_Buffer_t* bbP, MIH_C_LINK_POA_LIST_T *dataP);) -public_F4_codec(unsigned int MIH_C_LINK_STATES_RSP2String(MIH_C_LINK_STATES_RSP_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_LINK_STATES_RSP_encode(Bit_Buffer_t* bbP, MIH_C_LINK_STATES_RSP_T *dataP);) -public_F4_codec(void MIH_C_LINK_STATES_RSP_decode(Bit_Buffer_t* bbP, MIH_C_LINK_STATES_RSP_T *dataP);) -public_F4_codec(void MIH_C_LINK_STATUS_REQ_encode(Bit_Buffer_t* bbP, MIH_C_LINK_STATUS_REQ_T *dataP);) -public_F4_codec(void MIH_C_LINK_STATUS_REQ_decode(Bit_Buffer_t* bbP, MIH_C_LINK_STATUS_REQ_T *dataP);) -public_F4_codec(void MIH_C_LINK_STATUS_RSP_encode(Bit_Buffer_t* bbP, MIH_C_LINK_STATUS_RSP_T *dataP);) -public_F4_codec(void MIH_C_LINK_STATUS_RSP_decode(Bit_Buffer_t* bbP, MIH_C_LINK_STATUS_RSP_T *dataP);) -public_F4_codec(unsigned int MIH_C_LINK_STATES_REQ2String2(MIH_C_LINK_STATES_REQ_T *dataP, char* bufP);) -public_F4_codec(unsigned int MIH_C_LINK_DESC_REQ2String2(MIH_C_LINK_DESC_REQ_T *dataP, char* bufP);) -public_F4_codec(void MIH_C_LINK_TUPLE_ID_encode(Bit_Buffer_t* bbP, MIH_C_LINK_TUPLE_ID_T *dataP);) -public_F4_codec(void MIH_C_LINK_TUPLE_ID_decode(Bit_Buffer_t* bbP, MIH_C_LINK_TUPLE_ID_T *dataP);) -public_F4_codec(void MIH_C_LINK_DET_INFO_encode(Bit_Buffer_t* bbP, MIH_C_LINK_DET_INFO_T *dataP);) -public_F4_codec(void MIH_C_LINK_DET_INFO_decode(Bit_Buffer_t* bbP, MIH_C_LINK_DET_INFO_T *dataP);) -public_F4_codec(unsigned int MIH_C_LINK_AC_ATTR2String2(MIH_C_LINK_AC_ATTR_T *dataP, char* bufP);) -public_F4_codec(unsigned int MIH_C_TH_ACTION2String2(MIH_C_TH_ACTION_T *actionP, char* bufP);) -public_F4_codec(unsigned int MIH_C_LINK_AC_TYPE2String2(MIH_C_LINK_AC_TYPE_T *dataP, char* bufP);) -public_F4_codec(unsigned int MIH_C_THRESHOLD_XDIR2String2(MIH_C_THRESHOLD_XDIR_T *valP, char* bufP);) -public_F4_codec(unsigned int MIH_C_LINK_PARAM_GEN2String2(MIH_C_LINK_PARAM_GEN_T *valP, char* bufP);) -public_F4_codec(unsigned int MIH_C_LINK_AC_RESULT2String2(MIH_C_LINK_AC_RESULT_T *dataP, char* bufP);) - -#endif -/** @}*/ - diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F9_data_types_for_qos_codec.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F9_data_types_for_qos_codec.h deleted file mode 100755 index 28d126140a..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_F9_data_types_for_qos_codec.h +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_F9_data_types_for_qos_codec.h - * \brief This file defines the prototypes of the functions for coding and decoding Data type for QOS defined in Std 802.21-2008 Table F9. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ -/** \defgroup MIH_C_F9_DATA_TYPES_FOR_QOS F9 Data types for QOS - * \ingroup MIH_C_INTERFACE - * - * @{ - */ - -#ifndef __MIH_C_F9_DATA_TYPES_FOR_QOS_CODEC_H__ -# define __MIH_C_F9_DATA_TYPES_FOR_QOS_CODEC_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_F9_DATA_TYPES_FOR_QOS_CODEC_C -# define private_F9_codec(x) x -# define protected_F9_codec(x) x -# define public_F9_codec(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_F9_codec(x) -# define protected_F9_codec(x) extern x -# define public_F9_codec(x) extern x -# else -# define private_F9_codec(x) -# define protected_F9_codec(x) -# define public_F9_codec(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -public_F9_codec(unsigned int MIH_C_MIN_PK_TX_DELAY2String(MIH_C_MIN_PK_TX_DELAY_T *dataP, char* bufP);) -public_F9_codec(void MIH_C_MIN_PK_TX_DELAY_encode(Bit_Buffer_t* bbP, MIH_C_MIN_PK_TX_DELAY_T *dataP);) -public_F9_codec(void MIH_C_MIN_PK_TX_DELAY_decode(Bit_Buffer_t* bbP, MIH_C_MIN_PK_TX_DELAY_T *dataP);) - -public_F9_codec(unsigned int MIH_C_AVG_PK_TX_DELAY2String(MIH_C_AVG_PK_TX_DELAY_T *dataP, char* bufP);) -public_F9_codec(void MIH_C_AVG_PK_TX_DELAY_encode(Bit_Buffer_t* bbP, MIH_C_AVG_PK_TX_DELAY_T *dataP);) -public_F9_codec(void MIH_C_AVG_PK_TX_DELAY_decode(Bit_Buffer_t* bbP, MIH_C_AVG_PK_TX_DELAY_T *dataP);) - -public_F9_codec(unsigned int MIH_C_MAX_PK_TX_DELAY2String(MIH_C_MAX_PK_TX_DELAY_T *dataP, char* bufP);) -public_F9_codec(void MIH_C_MAX_PK_TX_DELAY_encode(Bit_Buffer_t* bbP, MIH_C_MAX_PK_TX_DELAY_T *dataP);) -public_F9_codec(void MIH_C_MAX_PK_TX_DELAY_decode(Bit_Buffer_t* bbP, MIH_C_MAX_PK_TX_DELAY_T *dataP);) - -public_F9_codec(unsigned int MIH_C_PK_DELAY_JITTER2String(MIH_C_PK_DELAY_JITTER_T *dataP, char* bufP);) -public_F9_codec(void MIH_C_PK_DELAY_JITTER_encode(Bit_Buffer_t* bbP, MIH_C_PK_DELAY_JITTER_T *dataP);) -public_F9_codec(void MIH_C_PK_DELAY_JITTER_decode(Bit_Buffer_t* bbP, MIH_C_PK_DELAY_JITTER_T *dataP);) - -public_F9_codec(unsigned int MIH_C_PK_LOSS_RATE2String(MIH_C_PK_LOSS_RATE_T *dataP, char* bufP);) -public_F9_codec(void MIH_C_PK_LOSS_RATE_encode(Bit_Buffer_t* bbP, MIH_C_PK_LOSS_RATE_T *dataP);) -public_F9_codec(void MIH_C_PK_LOSS_RATE_decode(Bit_Buffer_t* bbP, MIH_C_PK_LOSS_RATE_T *dataP);) - -public_F9_codec(unsigned int MIH_C_QOS_PARAM_VAL2String(MIH_C_QOS_PARAM_VAL_T *dataP, char* bufP);) -public_F9_codec(void MIH_C_QOS_PARAM_VAL_encode(Bit_Buffer_t* bbP, MIH_C_QOS_PARAM_VAL_T *dataP);) -public_F9_codec(void MIH_C_QOS_PARAM_VAL_decode(Bit_Buffer_t* bbP, MIH_C_QOS_PARAM_VAL_T *dataP);) - -#endif -/** @}*/ diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_L2_type_values_for_tlv_encoding.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_L2_type_values_for_tlv_encoding.h deleted file mode 100755 index faf84fac6e..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_L2_type_values_for_tlv_encoding.h +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_L2_type_values_for_tlv_encoding.h - * \brief This file defines the prototypes of the functions for coding and decoding Data type for MIHF identification defined in Std 802.21-2008 Table L2. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ -/** \defgroup MIH_C_L2_TYPE_VALUES_FOR_TLV_ENCODING L2 Type values for TLV encoding. - * \ingroup MIH_C_INTERFACE - * - * @{ - */ - -#ifndef __MIH_C_L2_TYPE_VALUES_FOR_TLV_ENCODING_H__ -# define __MIH_C_L2_TYPE_VALUES_FOR_TLV_ENCODING_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_L2_TYPE_VALUES_FOR_TLV_ENCODING_C -# define private_L2_codec(x) x -# define protected_L2_codec(x) x -# define public_L2_codec(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_L2_codec(x) -# define protected_L2_codec(x) extern x -# define public_L2_codec(x) extern x -# else -# define private_L2_codec(x) -# define protected_L2_codec(x) -# define public_L2_codec(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- - -public_L2_codec(unsigned int MIH_C_TLV2String(MIH_C_TLV_TYPE_T *typeP, char* bufP);) -/** @}*/ -#endif diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Constants.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Constants.h deleted file mode 100755 index 4c7873111b..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Constants.h +++ /dev/null @@ -1,110 +0,0 @@ - -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -/*! \file MIH_C_Link_Constants.h - * \brief This file defines constants, for the MIH Link SAP. - * \author BRIZZOLARA Davide, GAUTHIER Lionel, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MIH_C_LINK_CONSTANTS_H__ -#define __MIH_C_LINK_CONSTANTS_H__ - -#define MIH_C_BIT_0_VALUE 0x01 -#define MIH_C_BIT_1_VALUE 0x02 -#define MIH_C_BIT_2_VALUE 0x04 -#define MIH_C_BIT_3_VALUE 0x08 -#define MIH_C_BIT_4_VALUE 0x10 -#define MIH_C_BIT_5_VALUE 0x20 -#define MIH_C_BIT_6_VALUE 0x40 -#define MIH_C_BIT_7_VALUE 0x80 -#define MIH_C_BIT_8_VALUE 0x100 -#define MIH_C_BIT_9_VALUE 0x200 -#define MIH_C_BIT_10_VALUE 0x400 -#define MIH_C_BIT_11_VALUE 0x800 -#define MIH_C_BIT_12_VALUE 0x1000 -#define MIH_C_BIT_13_VALUE 0x2000 -#define MIH_C_BIT_14_VALUE 0x4000 -#define MIH_C_BIT_15_VALUE 0x8000 -#define MIH_C_BIT_16_VALUE 0x10000 -#define MIH_C_BIT_17_VALUE 0x20000 -#define MIH_C_BIT_18_VALUE 0x40000 -#define MIH_C_BIT_19_VALUE 0x80000 -#define MIH_C_BIT_20_VALUE 0x100000 -#define MIH_C_BIT_21_VALUE 0x200000 -#define MIH_C_BIT_22_VALUE 0x400000 -#define MIH_C_BIT_23_VALUE 0x800000 -#define MIH_C_BIT_24_VALUE 0x1000000 -#define MIH_C_BIT_25_VALUE 0x2000000 -#define MIH_C_BIT_26_VALUE 0x4000000 -#define MIH_C_BIT_27_VALUE 0x8000000 -#define MIH_C_BIT_28_VALUE 0x10000000 -#define MIH_C_BIT_29_VALUE 0x20000000 -#define MIH_C_BIT_30_VALUE 0x40000000 -#define MIH_C_BIT_31_VALUE 0x80000000 - -#define MIH_C_3GPP_ADDR_LENGTH 16 -#define MIH_C_3GPP2_ADDR_LENGTH 8 -#define MIH_C_OTHER_L2_ADDR_LENGTH 64 -#define MIH_C_LINK_SCAN_RSP_LENGTH 8 -#define MIH_C_THRESHOLD_LIST_LENGTH 8 -#define MIH_C_LINK_ADDR_LIST_LENGTH 8 -#define MIH_C_QOS_LIST_LENGTH 255 -#define MIH_C_LINK_STATUS_REQ_LIST_LENGTH 32 -#define MIH_C_LINK_CFG_PARAM_LIST_LENGTH 16 - - -#endif - -#ifndef __MIH_C_IANA_CONSTANTS_H__ -#define __MIH_C_IANA_CONSTANTS_H__ -#define IANA_ADDR_FAMILY_RESERVED 0 -#define IANA_ADDR_FAMILY_IP 1 -#define IANA_ADDR_FAMILY_IP6 2 -#define IANA_ADDR_FAMILY_NSAP 3 -#define IANA_ADDR_FAMILY_HDLC 4 -#define IANA_ADDR_FAMILY_BBN_1822 5 -#define IANA_ADDR_FAMILY_802 6 -#define IANA_ADDR_FAMILY_E_163 7 -#define IANA_ADDR_FAMILY_E_164 8 -#define IANA_ADDR_FAMILY_F_69 9 -#define IANA_ADDR_FAMILY_X_121 10 -#define IANA_ADDR_FAMILY_IPX 11 -#define IANA_ADDR_FAMILY_Appletalk 12 -#define IANA_ADDR_FAMILY_Decnet_IV 13 -#define IANA_ADDR_FAMILY_Banyan_Vines 14 -#define IANA_ADDR_FAMILY_E_164_with_NSAP 15 -#define IANA_ADDR_FAMILY_DNS 16 -// More defined values, see http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml -#endif diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Messages.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Messages.h deleted file mode 100755 index e92ae89c7b..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Messages.h +++ /dev/null @@ -1,315 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -/*! \file MIH_C_Link_Messages.h - * \brief This file defines the messages of the MIH Link SAP. - * \author BRIZZOLARA Davide, GAUTHIER Lionel, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ -/** \defgroup MIH_C_LINK_MESSAGES 802.21 Link Messages - * \ingroup MIH_C_INTERFACE - * - * @{ - */ - -#ifndef __MIH_C_LINK_MESSAGES_H__ -#define __MIH_C_LINK_MESSAGES_H__ -#include <sys/types.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -#define MIH_C_PROTOCOL_VERSION 1 -#define MIH_C_MESSAGE_ID(SID, OC, AID) ((u_int16_t)SID << 12) | ((u_int16_t)OC << 10) | ((u_int16_t)AID) -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -#define MIH_C_MESSAGE_LINK_REGISTER_INDICATION_ID MIH_C_MESSAGE_ID(1, 3, 6) -#endif -#define MIH_C_MESSAGE_LINK_DETECTED_INDICATION_ID MIH_C_MESSAGE_ID(2, 3, 1) -#define MIH_C_MESSAGE_LINK_UP_INDICATION_ID MIH_C_MESSAGE_ID(2, 3, 2) -#define MIH_C_MESSAGE_LINK_DOWN_INDICATION_ID MIH_C_MESSAGE_ID(2, 3, 3) -#define MIH_C_MESSAGE_LINK_PARAMETERS_REPORT_INDICATION_ID MIH_C_MESSAGE_ID(2, 3, 5) -#define MIH_C_MESSAGE_LINK_GOING_DOWN_INDICATION_ID MIH_C_MESSAGE_ID(2, 3, 6) -#define MIH_C_MESSAGE_LINK_HANDOVER_IMMINENT_INDICATION_ID MIH_C_MESSAGE_ID(2, 3, 7) -#define MIH_C_MESSAGE_LINK_HANDOVER_COMPLETE_INDICATION_ID MIH_C_MESSAGE_ID(2, 3, 8) -#define MIH_C_MESSAGE_LINK_PDU_TRANSMIT_STATUS_INDICATION_ID MIH_C_MESSAGE_ID(2, 3, 9) -#define MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_REQUEST_ID MIH_C_MESSAGE_ID(1, 1, 1) -#define MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_CONFIRM_ID MIH_C_MESSAGE_ID(1, 0, 1) -#define MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_REQUEST_ID MIH_C_MESSAGE_ID(1, 1, 4) -#define MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_CONFIRM_ID MIH_C_MESSAGE_ID(1, 0, 4) -#define MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_REQUEST_ID MIH_C_MESSAGE_ID(1, 1, 5) -#define MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_CONFIRM_ID MIH_C_MESSAGE_ID(1, 0, 5) -#define MIH_C_MESSAGE_LINK_GET_PARAMETERS_REQUEST_ID MIH_C_MESSAGE_ID(3, 1, 1) -#define MIH_C_MESSAGE_LINK_GET_PARAMETERS_CONFIRM_ID MIH_C_MESSAGE_ID(3, 0, 1) -#define MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_REQUEST_ID MIH_C_MESSAGE_ID(3, 1, 2) -#define MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_CONFIRM_ID MIH_C_MESSAGE_ID(3, 0, 2) -#define MIH_C_MESSAGE_LINK_ACTION_REQUEST_ID MIH_C_MESSAGE_ID(3, 1, 3) -#define MIH_C_MESSAGE_LINK_ACTION_CONFIRM_ID MIH_C_MESSAGE_ID(3, 0, 3) -//----------------------------------------------------------------------------- - - -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -/*! \struct MIH_C_Message_Link_Register_indication -* \brief Structure defining the message Link_Register.indication, ODTONE specific. -*/ -typedef struct MIH_C_Message_Link_Register_indication { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Register_indication_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Register_indication_t; - -#endif - -/*! \struct MIH_C_Message_Link_Detected_indication -* \brief Structure defining the message Link_Detected.indication -*/ -typedef struct MIH_C_Message_Link_Detected_indication { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Detected_indication_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Detected_indication_t; - - -/*! \struct MIH_C_Message_Link_Up_indication -* \brief Structure defining the message Link_Up.indication. -*/ -typedef struct MIH_C_Message_Link_Up_indication { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Up_indication_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Up_indication_t; - - - -/*! \struct MIH_C_Message_Link_Down_indication -* \brief Structure defining the message Link_Down.indication. -*/ -typedef struct MIH_C_Message_Link_Down_indication { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Down_indication_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Down_indication_t; - - -/*! \struct MIH_C_Message_Link_Parameters_Report_indication -* \brief Structure defining the message Link_Parameters_Report.indication. -*/ -typedef struct MIH_C_Message_Link_Parameters_Report_indication { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Parameters_Report_indication_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Parameters_Report_indication_t; - - -/*! \struct MIH_C_Message_Link_Going_Down_indication -* \brief Structure defining the message Link_Going_Down.indication. -*/ -typedef struct MIH_C_Message_Link_Going_Down_indication { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Going_Down_indication_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Going_Down_indication_t; - - - -/*! \struct MIH_C_Message_Link_Handover_Imminent_indication -* \brief Structure defining the message Link_Handover_Imminent.indication. -*/ -typedef struct MIH_C_Message_Link_Handover_Imminent_indication { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Handover_Imminent_indication_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Handover_Imminent_indication_t; - - -/*! \struct MIH_C_Message_Link_Handover_Complete_indication -* \brief Structure defining the message Link_Handover_Complete.indication. -*/ -typedef struct MIH_C_Message_Link_Handover_Complete_indication { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Handover_Complete_indication_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Handover_Complete_indication_t; - - -/*! \struct MIH_C_Message_Link_PDU_Transmit_Status_indication -* \brief Structure defining the message Link_PDU_Transmit_Status.indication. -*/ -typedef struct MIH_C_Message_Link_PDU_Transmit_Status_indication { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_PDU_Transmit_Status_indication_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_PDU_Transmit_Status_indication_t; - - -/*! \struct MIH_C_Message_Link_Capability_Discover_request -* \brief Structure defining the message Link_Capability_Discover.request. -*/ -typedef struct MIH_C_Message_Link_Capability_Discover_request { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Capability_Discover_request_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Capability_Discover_request_t; - - -/*! \struct MIH_C_Message_Link_Capability_Discover_confirm -* \brief Structure defining the message Link_Capability_Discover.confirm. -*/ -typedef struct MIH_C_Message_Link_Capability_Discover_confirm { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Capability_Discover_confirm_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Capability_Discover_confirm_t; - - -/*! \struct MIH_C_Message_Link_Event_Subscribe_request -* \brief Structure defining the message Link_Event_Subscribe.request. -*/ -typedef struct MIH_C_Message_Link_Event_Subscribe_request { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Event_Subscribe_request_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Event_Subscribe_request_t; - - -/*! \struct MIH_C_Message_Link_Event_Subscribe_confirm -* \brief Structure defining the message Link_Event_Subscribe.confirm. -*/ -typedef struct MIH_C_Message_Link_Event_Subscribe_confirm { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Event_Subscribe_confirm_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Event_Subscribe_confirm_t; - - -/*! \struct MIH_C_Message_Link_Event_Unsubscribe_request -* \brief Structure defining the message Link_Event_Unsubscribe.request. -*/ -typedef struct MIH_C_Message_Link_Event_Unsubscribe_request { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Event_Unsubscribe_request_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Event_Unsubscribe_request_t; - - -/*! \struct MIH_C_Message_Link_Event_Unsubscribe_confirm -* \brief Structure defining the message Link_Event_Unsubscribe.confirm. -*/ -typedef struct MIH_C_Message_Link_Event_Unsubscribe_confirm { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Event_Unsubscribe_confirm_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Event_Unsubscribe_confirm_t; - - -/*! \struct MIH_C_Message_Link_Get_Parameters_request -* \brief Structure defining the message Link_Get_Parameters.request. -*/ -typedef struct MIH_C_Message_Link_Get_Parameters_request { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Get_Parameters_request_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Get_Parameters_request_t; - - -/*! \struct MIH_C_Message_Link_Get_Parameters_confirm -* \brief Structure defining the message Link_Get_Parameters.confirm. -*/ -typedef struct MIH_C_Message_Link_Get_Parameters_confirm { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Get_Parameters_confirm_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Get_Parameters_confirm_t; - - -/*! \struct MIH_C_Message_Link_Configure_Thresholds_request -* \brief Structure defining the message Link_Configure_Thresholds.request. -*/ -typedef struct MIH_C_Message_Link_Configure_Thresholds_request { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Configure_Thresholds_request_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Configure_Thresholds_request_t; - - -/*! \struct MIH_C_Message_Link_Configure_Thresholds_confirm -* \brief Structure defining the message Link_Configure_Thresholds.confirm. -*/ -typedef struct MIH_C_Message_Link_Configure_Thresholds_confirm { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Configure_Thresholds_confirm_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Configure_Thresholds_confirm_t; - - -/*! \struct MIH_C_Message_Link_Action_request -* \brief Structure defining the message Link_Action.request. -*/ -typedef struct MIH_C_Message_Link_Action_request { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Action_request_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Action_request_t; - - -/*! \struct MIH_C_Message_Link_Action_confirm -* \brief Structure defining the message Link_Action.confirm. -*/ -typedef struct MIH_C_Message_Link_Action_confirm { - MIH_C_HEADER_T header; /*!< \brief Header of the message. */ - MIH_C_MIHF_ID_T source; /*!< \brief Source of the message. */ - MIH_C_MIHF_ID_T destination; /*!< \brief Destination of the message. */ - MIH_C_Link_Action_confirm_t primitive; /*!< \brief Primitive. */ -} __attribute__((__packed__))MIH_C_Message_Link_Action_confirm_t; - - -#endif -/** @}*/ diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Primitives.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Primitives.h deleted file mode 100755 index 083b59a615..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Link_Primitives.h +++ /dev/null @@ -1,231 +0,0 @@ -/*************************************************************************** - MIH_C_Link_Primitives.h - description - ------------------- - copyright : (C) 2012 by Eurecom - email : davide.brizzolara@eurecom.fr; michelle.wetterwald@eurecom.fr -*************************************************************************** -Type definition and structure for ODTONE interface -***************************************************************************/ - -/** \defgroup MIH_C_LINK_PRIMITIVES 802.21 Link Primitives - * \ingroup MIH_C_INTERFACE - * - * @{ - */ - -#ifndef __MIH_C_LINK_PRIMITIVES_H__ -#define __MIH_C_LINK_PRIMITIVES_H__ -#include <sys/types.h> -//----------------------------------------------------------------------------- -#include "MIH_C_Types.h" -//----------------------------------------------------------------------------- -/*! \struct MIH_C_Link_Detected_indication -* \brief Structure defining the Link_Detected.indication MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.1 Link_Detected.indication) -*/ -typedef struct MIH_C_Link_Detected_indication { - MIH_C_LINK_DET_INFO_T LinkDetectedInfo; /*!< \brief Information of a detected link. */ -} __attribute__((__packed__))MIH_C_Link_Detected_indication_t; - -//----------------------------------------------------------------------------- -/*! \struct MIH_C_Link_Up_indication -* \brief Structure defining the Link_Up.indication MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.2 Link_Up.indication) -*/ -typedef struct MIH_C_Link_Up_indication { - MIH_C_LINK_TUPLE_ID_T LinkIdentifier; /*!< \brief Identifier of the link associated with the event. */ - MIH_C_LINK_ADDR_T *OldAccessRouter; /*!< \brief (Optional) Old Access Router link address.*/ - MIH_C_LINK_ADDR_T *NewAccessRouter; /*!< \brief (Optional) New Access Router link address. */ - MIH_C_IP_RENEWAL_FLAG_T *IPRenewalFlag; /*!< \brief (Optional) Indicates whether the MN needs to changeIP Address in the new PoA. */ - MIH_C_IP_MOB_MGMT_T *MobilityManagementSupport;/*!< \brief (Optional) Indicates the type of Mobility Management Protocol supported by the new PoA. */ -} __attribute__((__packed__))MIH_C_Link_Up_indication_t; - - - -/*! \struct MIH_C_Link_Down_indication -* \brief Structure defining the Link_Down.indication MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.3 Link_Down.indication) -*/ -typedef struct MIH_C_Link_Down_indication { - MIH_C_LINK_TUPLE_ID_T LinkIdentifier; /*!< \brief Identifier of the link associated with the event. */ - MIH_C_LINK_ADDR_T *OldAccessRouter; /*!< \brief (Optional) Old Access Router link address.*/ - MIH_C_LINK_DN_REASON_T ReasonCode; /*!< \brief Reason why the link went down. */ -} __attribute__((__packed__))MIH_C_Link_Down_indication_t; - -TYPEDEF_LIST(MIH_C_LINK_PARAM_RPT, 16); -/*! \struct MIH_C_Link_Parameters_Report_indication -* \brief Structure defining the Link_Parameters_Report.indication MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.4 Link_Parameters_Report.indication) -*/ -typedef struct MIH_C_Link_Parameters_Report_indication { - MIH_C_LINK_TUPLE_ID_T LinkIdentifier; /*!< \brief Identifier of the link associated with the event. */ - LIST(MIH_C_LINK_PARAM_RPT, LinkParametersReportList) /*!< \brief A list of Link Parameter Report.*/ -} __attribute__((__packed__))MIH_C_Link_Parameters_Report_indication_t; - - -/*! \struct MIH_C_Link_Going_Down_indication -* \brief Structure defining the Link_Going_Down.indication MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.5 Link_Going_Down.indication) -*/ -typedef struct MIH_C_Link_Going_Down_indication { - MIH_C_LINK_TUPLE_ID_T LinkIdentifier; /*!< \brief Identifier of the link associated with the event. */ - UNSIGNED_INT2( - TimeInterval) /*!< \brief Time Interval (in milliseconds) specifies the time interval at which the link is expected to go down. A value of "0" is specified if the time interval is unknown.*/ - MIH_C_LINK_GD_REASON_T LinkGoingDownReason; /*!< \brief The reason why the link is going to be down. */ - -} __attribute__((__packed__))MIH_C_Link_Going_Down_indication_t; - - - -/*! \struct MIH_C_Link_Handover_Imminent_indication -* \brief Structure defining the Link_Handover_Imminent.indication MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.6 Link_Handover_Imminent.indication) -*/ -typedef struct MIH_C_Link_Handover_Imminent_indication { - MIH_C_LINK_TUPLE_ID_T OldLinkIdentifier; /*!< \brief Identifier of the old link. */ - MIH_C_LINK_TUPLE_ID_T NewLinkIdentifier; /*!< \brief Identifier of the new link. */ - MIH_C_LINK_ADDR_T *OldAccessRouter; /*!< \brief (Optional) Link address of old Access Router.*/ - MIH_C_LINK_ADDR_T *NewAccessRouter; /*!< \brief (Optional) Link address of new Access Router.*/ -} __attribute__((__packed__))MIH_C_Link_Handover_Imminent_indication_t; - - -/*! \struct MIH_C_Link_Handover_Complete_indication -* \brief Structure defining the Link_Handover_Complete.indication MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.7 Link_Handover_Complete.indication) -*/ -typedef struct MIH_C_Link_Handover_Complete_indication { - MIH_C_LINK_TUPLE_ID_T OldLinkIdentifier; /*!< \brief Identifier of the old link. */ - MIH_C_LINK_TUPLE_ID_T NewLinkIdentifier; /*!< \brief Identifier of the new link. */ - MIH_C_LINK_ADDR_T *OldAccessRouter; /*!< \brief (Optional) Link address of old Access Router.*/ - MIH_C_LINK_ADDR_T *NewAccessRouter; /*!< \brief (Optional) Link address of new Access Router.*/ - MIH_C_STATUS_T LinkHandoverStatus; /*!< \brief Status of the link handover.*/ -} __attribute__((__packed__))MIH_C_Link_Handover_Complete_indication_t; - - -/*! \struct MIH_C_Link_PDU_Transmit_Status_indication -* \brief Structure defining the Link_PDU_Transmit_Status.indication MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.8 Link_PDU_Transmit_Status.indication) -*/ -typedef struct MIH_C_Link_PDU_Transmit_Status_indication { - MIH_C_LINK_TUPLE_ID_T LinkIdentifier; /*!< \brief Identifier of the link associated with the event. */ - UNSIGNED_INT2(PacketIdentifier) /*!< \brief Identifier for higher layer PDU on which this notification is generated. */ - BOOLEAN(TransmissionStatus) /*!< \brief Status of the transmitted packet. True: Success, False: Failure*/ -} __attribute__((__packed__))MIH_C_Link_PDU_Transmit_Status_indication_t; - - -/*! \struct MIH_C_Link_Capability_Discover_request -* \brief Structure defining the Link_Capability_Discover.request MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.9.1 Link_Capability_Discover.request) -*/ -typedef struct MIH_C_Link_Capability_Discover_request { -} __attribute__((__packed__))MIH_C_Link_Capability_Discover_request_t; - - -/*! \struct MIH_C_Link_Capability_Discover_confirm -* \brief Structure defining the Link_Capability_Discover.confirm MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.9.2 Link_Capability_Discover.confirm) -*/ -typedef struct MIH_C_Link_Capability_Discover_confirm { - MIH_C_STATUS_T Status; /*!< \brief Status of operation. Code 3 (Authorization Failure) is not applicable.*/ - MIH_C_LINK_EVENT_LIST_T - *SupportedLinkEventList; /*!< \brief List of link-layer events supported by the link layer. This parameter is not included if Status does not indicate “Success.†*/ - MIH_C_LINK_CMD_LIST_T - *SupportedLinkCommandList; /*!< \brief List of link-layer commands supported by the link layer. This parameter is not included if Status does not indicate “Success.†*/ -} __attribute__((__packed__))MIH_C_Link_Capability_Discover_confirm_t; - - -/*! \struct MIH_C_Link_Event_Subscribe_request -* \brief Structure defining the Link_Event_Subscribe.request MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.10.1 Link_Event_Subscribe.request) -*/ -typedef struct MIH_C_Link_Event_Subscribe_request { - MIH_C_LINK_EVENT_LIST_T RequestedLinkEventList; /*!< \brief List of link-layer events that for which the subscriber would like to receive indications. */ -} __attribute__((__packed__))MIH_C_Link_Event_Subscribe_request_t; - - -/*! \struct MIH_C_Link_Event_Subscribe_confirm -* \brief Structure defining the Link_Event_Subscribe.confirm MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.10.2 Link_Event_Subscribe.confirm) -*/ -typedef struct MIH_C_Link_Event_Subscribe_confirm { - MIH_C_STATUS_T Status; /*!< \brief Status of operation. Code 3 (Authorization Failure) is not applicable.*/ - MIH_C_LINK_EVENT_LIST_T *ResponseLinkEventList; /*!< \brief List of successfully subscribed link events. This parameter is not included if Status does not indicate "Success".*/ -} __attribute__((__packed__))MIH_C_Link_Event_Subscribe_confirm_t; - - -/*! \struct MIH_C_Link_Event_Unsubscribe_request -* \brief Structure defining the Link_Event_Unsubscribe.request MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.11.1 Link_Event_Unsubscribe.request) -*/ -typedef struct MIH_C_Link_Event_Unsubscribe_request { - MIH_C_LINK_EVENT_LIST_T RequestedLinkEventList; /*!< \brief List of link-layer events for which indications need to be unsubscribed from the Event Source.*/ -} __attribute__((__packed__))MIH_C_Link_Event_Unsubscribe_request_t; - - -/*! \struct MIH_C_Link_Event_Unsubscribe_confirm -* \brief Structure defining the Link_Event_Unsubscribe.confirm MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.11.2 Link_Event_Unsubscribe.confirm) -*/ -typedef struct MIH_C_Link_Event_Unsubscribe_confirm { - MIH_C_STATUS_T Status; /*!< \brief Status of operation. Code 3 (Authorization Failure) is not applicable.*/ - MIH_C_LINK_EVENT_LIST_T *ResponseLinkEventList; /*!< \brief List of successfully unsubscribed link events. This parameter is not included if Status does not indicate “Success.†*/ -} __attribute__((__packed__))MIH_C_Link_Event_Unsubscribe_confirm_t; - - -/*! \struct MIH_C_Link_Get_Parameters_request -* \brief Structure defining the Link_Get_Parameters.request MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.12.1 Link_Get_Parameters.request) -*/ -typedef struct MIH_C_Link_Get_Parameters_request { - LIST(MIH_C_LINK_PARAM_TYPE, LinkParametersRequest) /*!< \brief A list of link parameters for which status is requested.*/ - MIH_C_LINK_STATES_REQ_T LinkStatesRequest; /*!< \brief The link states to be requested.*/ - MIH_C_LINK_DESC_REQ_T LinkDescriptorsRequest; /*!< \brief The link descriptors to be requested. */ -} __attribute__((__packed__))MIH_C_Link_Get_Parameters_request_t; - - -/*! \struct MIH_C_Link_Get_Parameters_confirm -* \brief Structure defining the Link_Get_Parameters.confirm MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.12.1 Link_Get_Parameters.confirm) -*/ -typedef struct MIH_C_Link_Get_Parameters_confirm { - MIH_C_STATUS_T Status; /*!< \brief Status of operation. Code 3 (Authorization Failure) is not applicable.*/ - LIST(MIH_C_LINK_PARAM, *LinkParametersStatusList) /*!< \brief A list of measurable link parameters and their current values.*/ - LIST(MIH_C_LINK_STATES_RSP, *LinkStatesResponse) /*!< \brief The current link state information.*/ - LIST(MIH_C_LINK_DESC_RSP, *LinkDescriptorsResponse) /*!< \brief The descriptors of a link.*/ -} __attribute__((__packed__))MIH_C_Link_Get_Parameters_confirm_t; - -TYPEDEF_LIST(MIH_C_LINK_CFG_PARAM, MIH_C_LINK_CFG_PARAM_LIST_LENGTH); -/*! \struct MIH_C_Link_Configure_Thresholds_request -* \brief Structure defining the Link_Configure_Thresholds.request MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.13.1 Link_Configure_Thresholds.request) -*/ -typedef struct MIH_C_Link_Configure_Thresholds_request { - LIST(MIH_C_LINK_CFG_PARAM, LinkConfigureParameterList) /*!< \brief A list of link threshold parameters.*/ -} __attribute__((__packed__))MIH_C_Link_Configure_Thresholds_request_t; - -#define MIH_C_LINK_CFG_STATUS_LIST_LENGTH 16 -TYPEDEF_LIST(MIH_C_LINK_CFG_STATUS, MIH_C_LINK_CFG_STATUS_LIST_LENGTH); -/*! \struct MIH_C_Link_Configure_Thresholds_confirm -* \brief Structure defining the Link_Configure_Thresholds.confirm MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.13.2 Link_Configure_Thresholds.confirm) -*/ -typedef struct MIH_C_Link_Configure_Thresholds_confirm { - MIH_C_STATUS_T Status; /*!< \brief Status of operation. Code 3 (Authorization Failure) is not applicable.*/ - LIST(MIH_C_LINK_CFG_STATUS, *LinkConfigureStatusList) /*!< \brief A list of Link Configure Status. This parameter is not included if Status does not indicate “Success.â€*/ -} __attribute__((__packed__))MIH_C_Link_Configure_Thresholds_confirm_t; - - -/*! \struct MIH_C_Link_Action_request -* \brief Structure defining the Link_Action.request MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.14.1 Link_Action.request) -*/ -typedef struct MIH_C_Link_Action_request { - // MIH_C_LINK_ACTION_REQ_T - MIH_C_LINK_ACTION_T LinkAction; /*!< \brief Specifies the action to perform. */ - UNSIGNED_INT2( - ExecutionDelay) /*!< \brief Time (in ms) to elapse before the action needs to be taken. A value of 0 indicates that the action is taken immediately. Time elapsed is calculated from the instance the request arrives until the time when the execution of the action is carried out. */ - MIH_C_LINK_ADDR_T *PoALinkAddress; /*!< \brief (Optional) The PoA link address to forward data to. This parameter is used when DATA_FWD_REQ action is requested. */ -} __attribute__((__packed__))MIH_C_Link_Action_request_t; - - -/*! \struct MIH_C_Link_Action_confirm -* \brief Structure defining the Link_Action.confirm MIH_LINK_SAP primitive (see IEEE Std 802.21-2008 7.3.14.2 Link_Action.confirm) -*/ -typedef struct MIH_C_Link_Action_confirm { - MIH_C_STATUS_T Status; /*!< \brief Status of operation. Code 3 (Authorization Failure) is not applicable.*/ - LIST(MIH_C_LINK_SCAN_RSP, - *ScanResponseSet) /*!< \brief (Optional) A list of discovered links and related information. This parameter is not included if Status does not indicate “Success.†*/ - MIH_C_LINK_AC_RESULT_T *LinkActionResult; /*!< \brief Specifies whether the link action was successful. This parameter is not included if Status does not indicate “Success.†*/ -} __attribute__((__packed__))MIH_C_Link_Action_confirm_t; - -/*! \struct MIH_C_Link_Register_indication -* \brief Structure defining the MIH_C_Link_Register.indication MIH_LINK_SAP primitive (ODTONE specific Link_Register - 101) -*/ -typedef struct { - MIH_C_LINK_ID_T Link_Id; -} __attribute__((__packed__))MIH_C_Link_Register_indication_t; - - -#endif -/** @}*/ diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Medieval_extensions.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Medieval_extensions.h deleted file mode 100755 index 91f907a478..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Medieval_extensions.h +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_Medieval_extensions.h - * \brief This file defines the prototypes of the functions for coding and decoding data types defined by the Medieval project. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ -/** \defgroup MIH_C_MEDIEVAL_EXTENSIONS Extensions to 802.21 defined by MEDIVAL IST Project. - * \ingroup MIH_C_INTERFACE - * - * @{ - */ -#ifndef __MIH_C_MEDIEVAL_EXTENSIONS_H__ -# define __MIH_C_MEDIEVAL_EXTENSIONS_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_MEDIEVAL_EXTENSIONS_C -# define private_Medieval_extensions(x) x -# define protected_Medieval_extensions(x) x -# define public_Medieval_extensions(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_Medieval_extensions(x) -# define protected_Medieval_extensions(x) extern x -# define public_Medieval_extensions(x) extern x -# else -# define private_Medieval_extensions(x) -# define protected_Medieval_extensions(x) -# define public_Medieval_extensions(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -public_Medieval_extensions(unsigned int MIH_C_PROTO2String (MIH_C_PROTO_T *protoP,char* bufP);) -public_Medieval_extensions(unsigned int MIH_C_IP_TUPLE2String(MIH_C_IP_TUPLE_T *dataP, char* bufP);) -public_Medieval_extensions(void MIH_C_IP_TUPLE_encode(Bit_Buffer_t* bbP, MIH_C_IP_TUPLE_T *dataP);) -public_Medieval_extensions(void MIH_C_IP_TUPLE_decode(Bit_Buffer_t* bbP, MIH_C_IP_TUPLE_T *dataP);) -public_Medieval_extensions(unsigned int MIH_C_FLOW_ID2String(MIH_C_FLOW_ID_T *dataP, char* bufP);) -public_Medieval_extensions(void MIH_C_FLOW_ID_encode(Bit_Buffer_t* bbP, MIH_C_FLOW_ID_T *dataP);) -public_Medieval_extensions(void MIH_C_FLOW_ID_decode(Bit_Buffer_t* bbP, MIH_C_FLOW_ID_T *dataP);) -public_Medieval_extensions(unsigned int MIH_C_MARK2String(MIH_C_MARK_T *dataP, char* bufP);) -public_Medieval_extensions(void MIH_C_MARK_encode(Bit_Buffer_t* bbP, MIH_C_MARK_T *dataP);) -public_Medieval_extensions(void MIH_C_MARK_decode(Bit_Buffer_t* bbP, MIH_C_MARK_T *dataP);) -public_Medieval_extensions(unsigned int MIH_C_QOS2String(MIH_C_QOS_T *dataP, char* bufP);) -public_Medieval_extensions(void MIH_C_QOS_encode(Bit_Buffer_t* bbP, MIH_C_QOS_T *dataP);) -public_Medieval_extensions(void MIH_C_QOS_decode(Bit_Buffer_t* bbP, MIH_C_QOS_T *dataP);) -public_Medieval_extensions(unsigned int MIH_C_RESOURCE_DESC2String(MIH_C_RESOURCE_DESC_T *dataP, char* bufP);) -public_Medieval_extensions(void MIH_C_RESOURCE_DESC_encode(Bit_Buffer_t* bbP, MIH_C_RESOURCE_DESC_T *dataP);) -public_Medieval_extensions(void MIH_C_RESOURCE_DESC_decode(Bit_Buffer_t* bbP, MIH_C_RESOURCE_DESC_T *dataP);) -public_Medieval_extensions(unsigned int MIH_C_FLOW_ATTRIBUTE2String(MIH_C_FLOW_ATTRIBUTE_T *dataP, char* bufP);) -public_Medieval_extensions(void MIH_C_FLOW_ATTRIBUTE_encode(Bit_Buffer_t* bbP, MIH_C_FLOW_ATTRIBUTE_T *dataP);) -public_Medieval_extensions(void MIH_C_FLOW_ATTRIBUTE_decode(Bit_Buffer_t* bbP, MIH_C_FLOW_ATTRIBUTE_T *dataP);) -public_Medieval_extensions(unsigned int MIH_C_LINK_AC_PARAM2String(MIH_C_LINK_AC_PARAM_T *dataP, char* bufP);) -public_Medieval_extensions(void MIH_C_LINK_AC_PARAM_encode(Bit_Buffer_t* bbP, MIH_C_LINK_AC_PARAM_T *dataP);) -public_Medieval_extensions(void MIH_C_LINK_AC_PARAM_decode(Bit_Buffer_t* bbP, MIH_C_LINK_AC_PARAM_T *dataP);) -public_Medieval_extensions(unsigned int MIH_C_LINK_ACTION2String(MIH_C_LINK_ACTION_T *dataP, char* bufP);) -public_Medieval_extensions(void MIH_C_LINK_ACTION_encode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_T *dataP);) -public_Medieval_extensions(void MIH_C_LINK_ACTION_decode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_T *dataP);) -public_Medieval_extensions(void MIH_C_LINK_ACTION_short_decode(Bit_Buffer_t* bbP, MIH_C_LINK_ACTION_T *dataP);) - -#endif -#endif -/** @}*/ - - diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Types.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Types.h deleted file mode 100755 index 1ac42be1e9..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_Types.h +++ /dev/null @@ -1,3070 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_Types.h - * \brief This file defines the 802.21 types or constants defined in Std 802.21-2008 Table F1, F2, F3, - * F4, F5, F6, F7, F8, F9, F12, F13, F19, F20, F22, L2. Some tables may be not implemented at all. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ -#ifndef __MIH_C_LINK_TYPES_H__ -#define __MIH_C_LINK_TYPES_H__ -#include <sys/types.h> -#include <linux/types.h> - -#ifndef USER_MODE -# define USER_MODE -# warning "Hack USER_MODE" -#endif -//----------------------------------------------------------------------------- -#include "MIH_C_Link_Constants.h" -#include "MIH_C_bit_buffer.h" -//----------------------------------------------------------------------------- -#define MIH_C_DEBUG_SERIALIZATION 1 -#define MIH_C_DEBUG_DESERIALIZATION 1 -//----------------------------------------------------------------------------- -#define STR(x) #x - -/** \defgroup MIH_C_INTERFACE 802.21 interface - * - */ - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.1 Basic data types -//----------------------------------------------------------------------------- - - -//----------------------- BITMAP(size) ---------------------------------------- -/*! \var typedef u_int8_t MIH_C_BITMAP8_T; - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A type definition for u_int8_t. - */ -typedef u_int8_t MIH_C_BITMAP8_T; -/*! \var typedef u_int16_t MIH_C_BITMAP16_T; - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A type definition for u_int16_t. - */ -typedef u_int16_t MIH_C_BITMAP16_T; -/*! \struct MIH_C_BITMAP24_T - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - */ -typedef struct MIH_C_BITMAP24 {u_int8_t val[3];}__attribute__((__packed__)) MIH_C_BITMAP24_T; -/*! \var typedef u_int32_t MIH_C_BITMAP32_T; - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A type definition for u_int32_t. - */ -typedef u_int32_t MIH_C_BITMAP32_T; -/*! \var typedef u_int64_t MIH_C_BITMAP64_T; - * \brief A type definition for u_int64_t. - */ -typedef u_int64_t MIH_C_BITMAP64_T; -/*! \struct MIH_C_BITMAP128_T - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - */ -typedef struct MIH_C_BITMAP128 {u_int64_t val[2];}__attribute__((__packed__)) MIH_C_BITMAP128_T; -/*! \struct MIH_C_BITMAP256_T - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - */ -typedef struct MIH_C_BITMAP256 {u_int64_t val[4];}__attribute__((__packed__)) MIH_C_BITMAP256_T; - -#ifdef MIH_C_F1_BASIC_DATA_TYPES_CODEC_C - /*! \def TYPEDEF_BITMAP6(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_BITMAP8_T. - */ - #define TYPEDEF_BITMAP6(DATA_TYPE_NAME) typedef MIH_C_BITMAP8_T DATA_TYPE_NAME ## _T;\ - void MIH_C_BITMAP8_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP8_T* dataP);\ - void MIH_C_BITMAP8_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP8_T* dataP);\ - inline unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP) {\ - return sprintf(buffP, "0x%02X", *bitmapP);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {\ - MIH_C_BITMAP8_encode(bbP, bitmapP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {MIH_C_BITMAP8_decode(bbP, bitmapP);}; - - /*! \def TYPEDEF_BITMAP8(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_BITMAP8_T. - */ - #define TYPEDEF_BITMAP8(DATA_TYPE_NAME) typedef MIH_C_BITMAP8_T DATA_TYPE_NAME ## _T;\ - void MIH_C_BITMAP8_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP8_T* dataP);\ - void MIH_C_BITMAP8_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP8_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP) {\ - return sprintf(buffP, "0x%02X", *bitmapP);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {\ - MIH_C_BITMAP8_encode(bbP, bitmapP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {MIH_C_BITMAP8_decode(bbP, bitmapP);}; - - /*! \def TYPEDEF_BITMAP16(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_BITMAP16_T. - */ - #define TYPEDEF_BITMAP16(DATA_TYPE_NAME) typedef MIH_C_BITMAP16_T DATA_TYPE_NAME ## _T;\ - void MIH_C_BITMAP16_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP16_T* dataP);\ - void MIH_C_BITMAP16_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP16_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP) {\ - return sprintf(buffP, "0x%04X", *bitmapP);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {\ - MIH_C_BITMAP16_encode(bbP, bitmapP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {MIH_C_BITMAP16_decode(bbP, bitmapP);}; - - /*! \def TYPEDEF_BITMAP20(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_BITMAP24_T. - */ - #define TYPEDEF_BITMAP20(DATA_TYPE_NAME) typedef MIH_C_BITMAP24_T DATA_TYPE_NAME ## _T;\ - void MIH_C_BITMAP24_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP24_T* dataP);\ - void MIH_C_BITMAP24_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP24_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP) {\ - return sprintf(buffP, "0x%02X%02X%02X", bitmapP->val[0], bitmapP->val[1], bitmapP->val[2]);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {\ - MIH_C_BITMAP24_encode(bbP, bitmapP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {MIH_C_BITMAP24_decode(bbP, bitmapP);}; - - /*! \def TYPEDEF_BITMAP32(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_BITMAP32_T. - */ - #define TYPEDEF_BITMAP32(DATA_TYPE_NAME) typedef MIH_C_BITMAP32_T DATA_TYPE_NAME ## _T;\ - void MIH_C_BITMAP32_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP32_T* dataP);\ - void MIH_C_BITMAP32_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP32_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP) {\ - return sprintf(buffP, "0x%08X", *bitmapP);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {\ - MIH_C_BITMAP32_encode(bbP, bitmapP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {MIH_C_BITMAP32_decode(bbP, bitmapP);}; - - /*! \def TYPEDEF_BITMAP64(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_BITMAP64_T. - */ - #define TYPEDEF_BITMAP64(DATA_TYPE_NAME) typedef MIH_C_BITMAP64_T DATA_TYPE_NAME ## _T;\ - void MIH_C_BITMAP64_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP64_T* dataP);\ - void MIH_C_BITMAP64_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP64_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP) {\ - unsigned int buffer_index = 0;\ - buffer_index = sprintf(buffP, "0x%08x", (MIH_C_UNSIGNED_INT4_T)(*bitmapP>>32));\ - buffer_index = sprintf(&buffP[buffer_index], "%08x", (MIH_C_UNSIGNED_INT4_T)(*bitmapP));\ - return buffer_index;\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {\ - MIH_C_BITMAP64_encode(bbP, bitmapP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {MIH_C_BITMAP64_decode(bbP, bitmapP);}; - - /*! \def TYPEDEF_BITMAP128(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_BITMAP128_T. - */ - #define TYPEDEF_BITMAP128(DATA_TYPE_NAME) typedef MIH_C_BITMAP128_T DATA_TYPE_NAME ## _T;\ - void MIH_C_BITMAP128_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP128_T* dataP);\ - void MIH_C_BITMAP128_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP128_T* dataP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {MIH_C_BITMAP128_encode(bbP, bitmapP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {MIH_C_BITMAP128_decode(bbP, bitmapP);}; - - /*! \def TYPEDEF_BITMAP256(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_BITMAP256_T. - */ - #define TYPEDEF_BITMAP256(DATA_TYPE_NAME) typedef MIH_C_BITMAP256_T DATA_TYPE_NAME ## _T;\ - void MIH_C_BITMAP256_encode(Bit_Buffer_t* bbP, MIH_C_BITMAP256_T* dataP);\ - void MIH_C_BITMAP256_decode(Bit_Buffer_t* bbP, MIH_C_BITMAP256_T* dataP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {MIH_C_BITMAP256_encode(bbP, bitmapP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *bitmapP) {MIH_C_BITMAP256_decode(bbP, bitmapP);}; - -#else - #define TYPEDEF_BITMAP6(DATA_TYPE_NAME) typedef MIH_C_BITMAP8_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP); - - #define TYPEDEF_BITMAP8(DATA_TYPE_NAME) typedef MIH_C_BITMAP8_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP); - - #define TYPEDEF_BITMAP16(DATA_TYPE_NAME) typedef MIH_C_BITMAP16_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP); - - #define TYPEDEF_BITMAP20(DATA_TYPE_NAME) typedef MIH_C_BITMAP24_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP); - - #define TYPEDEF_BITMAP32(DATA_TYPE_NAME) typedef MIH_C_BITMAP32_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP); - - #define TYPEDEF_BITMAP64(DATA_TYPE_NAME) typedef MIH_C_BITMAP64_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *bitmapP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP); - - #define TYPEDEF_BITMAP128(DATA_TYPE_NAME) typedef MIH_C_BITMAP128_T DATA_TYPE_NAME ## _T;\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP); - - #define TYPEDEF_BITMAP256(DATA_TYPE_NAME) typedef MIH_C_BITMAP256_T DATA_TYPE_NAME ## _T;\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T* bitmapP); -#endif - -#define BITMAP6(VAR_NAME) MIH_C_BITMAP8_T VAR_NAME; -#define BITMAP8(VAR_NAME) MIH_C_BITMAP8_T VAR_NAME; -#define BITMAP16(VAR_NAME) MIH_C_BITMAP16_T VAR_NAME; -#define BITMAP20(VAR_NAME) MIH_C_BITMAP24_T VAR_NAME; -#define BITMAP24(VAR_NAME) MIH_C_BITMAP24_T VAR_NAME; -#define BITMAP32(VAR_NAME) MIH_C_BITMAP32_T VAR_NAME; -#define BITMAP64(VAR_NAME) MIH_C_BITMAP64_T VAR_NAME; -#define BITMAP128(VAR_NAME) MIH_C_BITMAP128_T VAR_NAME; -#define BITMAP256(VAR_NAME) MIH_C_BITMAP256_T VAR_NAME; - -//----------------------- CHOICE(DATATYPE1, DATATYPE2[,...]) ------------------ -/*! \var typedef u_int8_t MIH_C_CHOICE_T; - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A type definition for u_int8_t. - */ -typedef u_int8_t MIH_C_CHOICE_T; - -//----------------------- INTEGER(size) --------------------------------------- -/*! \var typedef int8_t MIH_C_INTEGER1_T; - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A type definition for int8_t. - */ -typedef int8_t MIH_C_INTEGER1_T; -/*! \var typedef int16_t MIH_C_INTEGER2_T; - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A type definition for int16_t. - */ -typedef int16_t MIH_C_INTEGER2_T; -/*! \var typedef int32_t MIH_C_INTEGER4_T; - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A type definition for int32_t. - */ -typedef int32_t MIH_C_INTEGER4_T; -/*! \var typedef int64_t MIH_C_INTEGER8_T; - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A type definition for int64_t. - */ -typedef int64_t MIH_C_INTEGER8_T; - -#ifdef MIH_C_F1_BASIC_DATA_TYPES_CODEC_C - /*! \def TYPEDEF_INTEGER1(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_INTEGER1_T. - */ - #define TYPEDEF_INTEGER1(DATA_TYPE_NAME) typedef MIH_C_INTEGER1_T DATA_TYPE_NAME ## _T;\ - void MIH_C_INTEGER1_encode(Bit_Buffer_t* bbP, MIH_C_INTEGER1_T* dataP);\ - void MIH_C_INTEGER1_decode(Bit_Buffer_t* bbP, MIH_C_INTEGER1_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP) {\ - return sprintf(buffP, "0x%02X", *dataP);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_INTEGER1_encode(bbP, (MIH_C_INTEGER1_T*)dataP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_INTEGER1_decode(bbP, (MIH_C_INTEGER1_T*)dataP);\ - }; - - /*! \def TYPEDEF_INTEGER2(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_INTEGER2_T. - */ - #define TYPEDEF_INTEGER2(DATA_TYPE_NAME) typedef MIH_C_INTEGER2_T DATA_TYPE_NAME ## _T;\ - void MIH_C_INTEGER2_encode(Bit_Buffer_t* bbP, MIH_C_INTEGER2_T* dataP);\ - void MIH_C_INTEGER2_decode(Bit_Buffer_t* bbP, MIH_C_INTEGER2_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP) {\ - return sprintf(buffP, "0x%04X", *dataP);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_INTEGER2_encode(bbP, (MIH_C_INTEGER2_T*)dataP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_INTEGER2_decode(bbP, (MIH_C_INTEGER2_T*)dataP);\ - }; - - /*! \def TYPEDEF_INTEGER4(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_INTEGER4_T. - */ - #define TYPEDEF_INTEGER4(DATA_TYPE_NAME) typedef MIH_C_INTEGER4_T DATA_TYPE_NAME ## _T;\ - void MIH_C_INTEGER4_encode(Bit_Buffer_t* bbP, MIH_C_INTEGER4_T* dataP);\ - void MIH_C_INTEGER4_decode(Bit_Buffer_t* bbP, MIH_C_INTEGER4_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP) {\ - return sprintf(buffP, "0x%08X", (MIH_C_INTEGER4_T)*dataP);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_INTEGER4_encode(bbP, (MIH_C_INTEGER4_T*)dataP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_INTEGER4_decode(bbP, (MIH_C_INTEGER4_T*)dataP);\ - }; - - /*! \def TYPEDEF_INTEGER8(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_INTEGER48T. - */ - #define TYPEDEF_INTEGER8(DATA_TYPE_NAME) typedef MIH_C_INTEGER8_T DATA_TYPE_NAME ## _T;\ - void MIH_C_INTEGER8_encode(Bit_Buffer_t* bbP, MIH_C_INTEGER8_T* dataP);\ - void MIH_C_INTEGER8_decode(Bit_Buffer_t* bbP, MIH_C_INTEGER8_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP) {\ - unsigned int buffer_index = 0;\ - buffer_index = sprintf(buffP, "0x%08x", (MIH_C_UNSIGNED_INT4_T)(*dataP>>32));\ - buffer_index = sprintf(&buffP[buffer_index], "%08x", (MIH_C_UNSIGNED_INT4_T)(*dataP));\ - return buffer_index;\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_INTEGER8_encode(bbP, (MIH_C_INTEGER8_T*)dataP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_INTEGER8_decode(bbP, (MIH_C_INTEGER8_T*)dataP);\ - }; -#else - #define TYPEDEF_INTEGER1(DATA_TYPE_NAME) typedef MIH_C_INTEGER1_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); - - #define TYPEDEF_INTEGER2(DATA_TYPE_NAME) typedef MIH_C_INTEGER2_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); - - #define TYPEDEF_INTEGER4(DATA_TYPE_NAME) typedef MIH_C_INTEGER4_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); - - #define TYPEDEF_INTEGER8(DATA_TYPE_NAME) typedef MIH_C_INTEGER8_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); -#endif - -/*! \def INTEGER1(VAR_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A variable declaration of type MIH_C_INTEGER1_T. - */ -#define INTEGER1(VAR_NAME) MIH_C_INTEGER1_T VAR_NAME; -/*! \def INTEGER2(VAR_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A variable declaration of type MIH_C_INTEGER2_T. - */ -#define INTEGER2(VAR_NAME) MIH_C_INTEGER2_T VAR_NAME; -/*! \def INTEGER4(VAR_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A variable declaration of type MIH_C_INTEGER4_T. - */ -#define INTEGER4(VAR_NAME) MIH_C_INTEGER4_T VAR_NAME; -/*! \def INTEGER8(VAR_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A variable declaration of type MIH_C_INTEGER8_T. - */ -#define INTEGER8(VAR_NAME) MIH_C_INTEGER8_T VAR_NAME; - - -//----------------------- UNSIGNED_INT(size) ---------------------------------- -/*! \var typedef int8_t MIH_C_UNSIGNED_INT1_T; - * \brief A type definition for int8_t. - */ -typedef u_int8_t MIH_C_UNSIGNED_INT1_T; -/*! \var u_int16_t MIH_C_UNSIGNED_INT2_T - * \brief A type definition for u_int16_t. - */ -typedef u_int16_t MIH_C_UNSIGNED_INT2_T; -/*! \var typedef u_int32_t MIH_C_UNSIGNED_INT4_T; - * \brief A type definition for u_int32_t. - */ -typedef u_int32_t MIH_C_UNSIGNED_INT4_T; -/*! \var u_int64_t MIH_C_UNSIGNED_INT8_T; - * \brief A type definition for u_int64_t. - */ -typedef u_int64_t MIH_C_UNSIGNED_INT8_T; - -#ifdef MIH_C_F1_BASIC_DATA_TYPES_CODEC_C - /*! \def TYPEDEF_UNSIGNED_INT1(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_UNSIGNED_INT1_T. - */ - #define TYPEDEF_UNSIGNED_INT1(DATA_TYPE_NAME) typedef MIH_C_UNSIGNED_INT1_T DATA_TYPE_NAME ## _T;\ - void MIH_C_UNSIGNED_INT1_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT1_T* dataP);\ - void MIH_C_UNSIGNED_INT1_decode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT1_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP) {\ - return sprintf(buffP, "0x%02X", *dataP);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_UNSIGNED_INT1_encode(bbP, dataP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_UNSIGNED_INT1_decode(bbP, dataP);\ - }; - - /*! \def TYPEDEF_UNSIGNED_INT2(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_UNSIGNED_INT2_T. - */ - #define TYPEDEF_UNSIGNED_INT2(DATA_TYPE_NAME) typedef MIH_C_UNSIGNED_INT2_T DATA_TYPE_NAME ## _T;\ - void MIH_C_UNSIGNED_INT2_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT2_T* dataP);\ - void MIH_C_UNSIGNED_INT2_decode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT2_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP) {\ - return sprintf(buffP, "0x%04X", *dataP);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_UNSIGNED_INT2_encode(bbP, dataP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_UNSIGNED_INT2_decode(bbP, dataP);\ - }; - - /*! \def TYPEDEF_UNSIGNED_INT4(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_UNSIGNED_INT4_T. - */ - #define TYPEDEF_UNSIGNED_INT4(DATA_TYPE_NAME) typedef MIH_C_UNSIGNED_INT4_T DATA_TYPE_NAME ## _T;\ - void MIH_C_UNSIGNED_INT4_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT4_T* dataP);\ - void MIH_C_UNSIGNED_INT4_decode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT4_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP) {\ - return sprintf(buffP, "0x%08X", *dataP);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_UNSIGNED_INT4_encode(bbP, dataP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_UNSIGNED_INT4_decode(bbP, dataP);\ - }; - - /*! \def TYPEDEF_UNSIGNED_INT8(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a MIH_C_UNSIGNED_INT8_T. - */ - #define TYPEDEF_UNSIGNED_INT8(DATA_TYPE_NAME) typedef MIH_C_UNSIGNED_INT8_T DATA_TYPE_NAME ## _T;\ - void MIH_C_UNSIGNED_INT8_encode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT8_T* dataP);\ - void MIH_C_UNSIGNED_INT8_decode(Bit_Buffer_t* bbP, MIH_C_UNSIGNED_INT8_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP) {\ - return sprintf(buffP, "0x%16X", *dataP);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_UNSIGNED_INT8_encode(bbP, dataP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_UNSIGNED_INT8_decode(bbP, dataP);\ - }; -#else - #define TYPEDEF_UNSIGNED_INT1(DATA_TYPE_NAME) typedef MIH_C_UNSIGNED_INT1_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); - - #define TYPEDEF_UNSIGNED_INT2(DATA_TYPE_NAME) typedef MIH_C_UNSIGNED_INT2_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); - - #define TYPEDEF_UNSIGNED_INT4(DATA_TYPE_NAME) typedef MIH_C_UNSIGNED_INT4_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); - - #define TYPEDEF_UNSIGNED_INT8(DATA_TYPE_NAME) typedef MIH_C_UNSIGNED_INT8_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* buffP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); -#endif - -/*! \def UNSIGNED_INT1(VAR_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A variable declaration of type MIH_C_UNSIGNED_INT1_T. - */ -#define UNSIGNED_INT1(VAR_NAME) MIH_C_UNSIGNED_INT1_T VAR_NAME; -/*! \def UNSIGNED_INT2(VAR_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A variable declaration of type MIH_C_UNSIGNED_INT2_T. - */ -#define UNSIGNED_INT2(VAR_NAME) MIH_C_UNSIGNED_INT2_T VAR_NAME; -/*! \def UNSIGNED_INT4(VAR_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A variable declaration of type MIH_C_UNSIGNED_INT4_T. - */ -#define UNSIGNED_INT4(VAR_NAME) MIH_C_UNSIGNED_INT4_T VAR_NAME; -/*! \def UNSIGNED_INT8(VAR_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A variable declaration of type MIH_C_UNSIGNED_INT8_T. - */ -#define UNSIGNED_INT8(VAR_NAME) MIH_C_UNSIGNED_INT8_T VAR_NAME; - -//----------------------- LIST(DATATYPE) -------------------------------------- -void MIH_C_LIST_LENGTH_encode(Bit_Buffer_t *bbP, u_int16_t lengthP); -void MIH_C_LIST_LENGTH_decode(Bit_Buffer_t *bbP, u_int16_t *lengthP); -u_int16_t MIH_C_LIST_LENGTH_get_encode_length(u_int16_t lengthP); - -#ifdef MIH_C_F1_BASIC_DATA_TYPES_CODEC_C - /*! \def TYPEDEF_LIST(DATA_TYPE_NAME, MAX_LENGTH) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a LIST of MAX_LENGTH elements of DATA_TYPE_NAME type, and its functions for de/serializing this type. - */ -#define TYPEDEF_LIST(DATA_TYPE_NAME, MAX_LENGTH) typedef struct DATA_TYPE_NAME ## _LIST { u_int16_t length; DATA_TYPE_NAME ## _T val[MAX_LENGTH];} DATA_TYPE_NAME ## _LIST_T;\ - extern void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *val);\ - extern void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *val);\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *val, char* bufP);\ - unsigned int DATA_TYPE_NAME ## _LIST2String(DATA_TYPE_NAME ## _LIST_T *listP, char* bufP) {\ - int index = 0;\ - unsigned int buffer_index = 0;\ - while ((index < listP->length) && (index < MAX_LENGTH)){\ - buffer_index += sprintf(&bufP[buffer_index], "%s (%d) = ", STR(DATA_TYPE_NAME) , index);\ - buffer_index += DATA_TYPE_NAME ## 2String(&listP->val[index], &bufP[buffer_index]);\ - buffer_index += sprintf(&bufP[buffer_index], " ");\ - index = index + 1;\ - }\ - return buffer_index;\ - };\ - void DATA_TYPE_NAME ## _LIST_decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _LIST_T *listP) {\ - int index = 0;\ - MIH_C_LIST_LENGTH_decode(bbP, &listP->length);\ - if (listP->length > MAX_LENGTH) {printf("[MIH_C] ERROR DATA_TYPE_NAME ## _LIST_decode num elements in list out of bounds: %d, max is %d\n", listP->length, MAX_LENGTH);\ - } else {\ - while ((index < listP->length) && (index < MAX_LENGTH)){\ - DATA_TYPE_NAME ## _decode(bbP, &listP->val[index++]);\ - }\ - }\ - };\ - void DATA_TYPE_NAME ## _LIST_encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _LIST_T *listP) {\ - int index = 0;\ - if (listP->length > MAX_LENGTH) {\ - printf("[MIH_C] ERROR DATA_TYPE_NAME ## _LIST_encode num elements in list out of bounds: %d, max is %d\n", listP->length, MAX_LENGTH);\ - } else {\ - MIH_C_LIST_LENGTH_encode(bbP, listP->length);\ - while (index < listP->length) {\ - DATA_TYPE_NAME ## _encode(bbP, &listP->val[index++]);\ - }\ - }\ - };\ - void DATA_TYPE_NAME ## _LIST_init(DATA_TYPE_NAME ## _LIST_T *listP) {\ - listP->length = 0;\ - memset(listP->val, 0, MAX_LENGTH*sizeof(DATA_TYPE_NAME ## _T));\ - }; - -#else -#define TYPEDEF_LIST(DATA_TYPE_NAME, MAX_LENGTH) typedef struct DATA_TYPE_NAME ## _LIST { u_int16_t length; DATA_TYPE_NAME ## _T val[MAX_LENGTH];} DATA_TYPE_NAME ## _LIST_T;\ - extern unsigned int DATA_TYPE_NAME ## _LIST2String(DATA_TYPE_NAME ## _LIST_T *listP, char* bufP);\ - extern void DATA_TYPE_NAME ## _LIST_decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _LIST_T *listP);\ - extern void DATA_TYPE_NAME ## _LIST_encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _LIST_T *listP);\ - extern void DATA_TYPE_NAME ## _LIST_init(DATA_TYPE_NAME ## _LIST_T *listP); -#endif -#define LIST(DATA_TYPE_NAME, VAR_NAME) DATA_TYPE_NAME ## _LIST_T VAR_NAME ## _list; - - - -//----------------------- NULL ------------------------------------------------ -#define MIH_C_NULL_T u_int8_t - -//----------------------- OCTET(size) ----------------------------------------- -#ifdef MIH_C_F1_BASIC_DATA_TYPES_CODEC_C - /*! \def TYPEDEF_OCTET(DATA_TYPE_NAME, MAX_LENGTH) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a LIST of MAX_LENGTH octet elements, and its functions for de/serializing this type. - */ -#define TYPEDEF_OCTET(DATA_TYPE_NAME, LENGTH) typedef struct DATA_TYPE_NAME {u_int8_t val[LENGTH];} DATA_TYPE_NAME ## _T;\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* bufP) {\ - int index = 0;\ - unsigned int buffer_index = 0;\ - while ( index < LENGTH ){\ - buffer_index += sprintf(&bufP[buffer_index], "%02X", dataP->val[index]);\ - index = index + 1;\ - }\ - return buffer_index;\ - };\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) { BitBuffer_readMem(bbP, &dataP->val[0], LENGTH);};\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) { BitBuffer_writeMem(bbP, &dataP->val[0], LENGTH);}; -#else -#define TYPEDEF_OCTET(DATA_TYPE_NAME, LENGTH) typedef struct DATA_TYPE_NAME {u_int8_t val[LENGTH];} DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* bufP);\ - extern void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - extern void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); -#endif - -//----------------------- SEQUENCE(DATATYPE1, DATATYPE2[,...]) : NO MACRO ----- - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.2 General data types -//----------------------------------------------------------------------------- - -//----------------------- ENUMERATED ------------------------------------------ -TYPEDEF_UNSIGNED_INT1(MIH_C_ENUMERATED) - -#ifdef MIH_C_F2_GENERAL_DATA_TYPES_CODEC_C - /*! \def TYPEDEF_ENUMERATED(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as MIH_C_ENUMERATED_T, and its functions for de/serializing this type. - */ - #define TYPEDEF_ENUMERATED(DATA_TYPE_NAME) typedef MIH_C_ENUMERATED_T DATA_TYPE_NAME ## _T;\ - void MIH_C_ENUMERATED_encode(Bit_Buffer_t* bbP, MIH_C_ENUMERATED_T* dataP);\ - void MIH_C_ENUMERATED_decode(Bit_Buffer_t* bbP, MIH_C_ENUMERATED_T* dataP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_ENUMERATED_encode(bbP, dataP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {MIH_C_ENUMERATED_decode(bbP, dataP);}; -#else - #define TYPEDEF_ENUMERATED(DATA_TYPE_NAME) typedef MIH_C_ENUMERATED_T DATA_TYPE_NAME ## _T;\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); -#endif - -/*! \def ENUMERATED(VAR_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A variable declaration of type MIH_C_ENUMERATED_T. - */ -#define ENUMERATED(VAR_NAME) MIH_C_ENUMERATED_T VAR_NAME; - - -//----------------------- BOOLEAN --------------------------------------------- -TYPEDEF_ENUMERATED(MIH_C_BOOLEAN) - -#define MIH_C_BOOLEAN_TRUE (MIH_C_ENUMERATED_T)1 -#define MIH_C_BOOLEAN_FALSE (MIH_C_ENUMERATED_T)0 -#ifdef MIH_C_F2_GENERAL_DATA_TYPES_CODEC_C - /*! \def TYPEDEF_BOOLEAN(DATA_TYPE_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as MIH_C_BOOLEAN_T, and its functions for de/serializing this type. - */ - #define TYPEDEF_BOOLEAN(DATA_TYPE_NAME) typedef MIH_C_BOOLEAN_T DATA_TYPE_NAME ## _T;\ - void MIH_C_BOOLEAN_encode(Bit_Buffer_t* bbP, MIH_C_BOOLEAN_T* dataP);\ - void MIH_C_BOOLEAN_decode(Bit_Buffer_t* bbP, MIH_C_BOOLEAN_T* dataP);\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* bufP) {\ - unsigned int buffer_index = 0;\ - if (*dataP != MIH_C_BOOLEAN_FALSE) {\ - buffer_index += sprintf(&bufP[buffer_index], "TRUE");\ - } else {\ - buffer_index += sprintf(&bufP[buffer_index], "FALSE");\ - }\ - return buffer_index;\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_BOOLEAN_encode(bbP, dataP);};\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {MIH_C_ENUMERATED_decode(bbP, dataP);}; -#else - #define TYPEDEF_BOOLEAN(DATA_TYPE_NAME) typedef MIH_C_BOOLEAN_T DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* bufP);\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); -#endif - -/*! \def BOOLEAN(VAR_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief A variable declaration of type MIH_C_BOOLEAN_T. - */ -#define BOOLEAN(VAR_NAME) MIH_C_BOOLEAN_T VAR_NAME; - - -//----------------------- OCTET_STRING ---------------------------------------- -#ifdef MIH_C_F2_GENERAL_DATA_TYPES_CODEC_C - /*! \def TYPEDEF_OCTET_STRING(DATA_TYPE_NAME, MAX_LENGTH) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines DATA_TYPE_NAME as a LIST of MAX_LENGTH char elements, and its functions for de/serializing this type. - */ -#define TYPEDEF_OCTET_STRING(DATA_TYPE_NAME, MAX_LENGTH) typedef struct DATA_TYPE_NAME { u_int16_t length; u_int8_t val[MAX_LENGTH];} DATA_TYPE_NAME ## _T;\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *listP, char* bufP) {\ - memcpy(bufP, listP->val, listP->length);\ - bufP[listP->length] = 0;\ - return listP->length;\ - };\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *listP) {\ - MIH_C_LIST_LENGTH_decode(bbP, &listP->length);\ - if (listP->length > MAX_LENGTH) {printf("[MIH_C] ERROR DATA_TYPE_NAME ## _decode String length out of bounds: %d, max is %d\n", listP->length, MAX_LENGTH);\ - } else {\ - BitBuffer_readMem(bbP, listP->val, listP->length);\ - }\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *listP) {\ - if (listP->length > MAX_LENGTH) {\ - printf("[MIH_C] ERROR DATA_TYPE_NAME ## _encode String length out of bounds: %d, max is %d\n", listP->length, MAX_LENGTH);\ - } else {\ - MIH_C_LIST_LENGTH_encode(bbP, listP->length);\ - BitBuffer_writeMem(bbP, listP->val, listP->length);\ - }\ - };\ - void DATA_TYPE_NAME ## _set(DATA_TYPE_NAME ## _T *octet_strP, u_int8_t* strP, u_int16_t lengthP) {\ - if (lengthP > MAX_LENGTH) {\ - printf("[MIH_C] ERROR DATA_TYPE_NAME ## _set String length out of bounds\n");\ - octet_strP->length = 0;\ - } else {\ - octet_strP->length = lengthP;\ - if (strP != NULL) {\ - memcpy((char *)octet_strP->val, (char *)strP, lengthP);\ - } else {\ - memset((char *)octet_strP->val, 0, lengthP);\ - }\ - }\ - }; -#else -#define TYPEDEF_OCTET_STRING(DATA_TYPE_NAME, MAX_LENGTH) typedef struct DATA_TYPE_NAME { u_int16_t length; u_int8_t val[MAX_LENGTH];} DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *listP, char* bufP);\ - extern void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *listP);\ - extern void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *listP);\ - extern void DATA_TYPE_NAME ## _set(DATA_TYPE_NAME ## _T *octet_strP, u_int8_t* strP, u_int16_t lengthP); -#endif - - -//----------------------- PERCENTAGE ------------------------------------------ -TYPEDEF_UNSIGNED_INT1(MIH_C_PERCENTAGE); -/*! \var PERCENTAGE(VAR_NAME) - * \ingroup MIH_C_F1_BASIC_DATA_TYPES - * \brief Defines VAR_NAME as MIH_C_PERCENTAGE_T. - */ -#define PERCENTAGE(VAR_NAME) MIH_C_PERCENTAGE_T VAR_NAME; - -//----------------------- STATUS ---------------------------------------------- -TYPEDEF_ENUMERATED(MIH_C_STATUS); -#define MIH_C_STATUS_SUCCESS (MIH_C_STATUS_T)0 -#define MIH_C_STATUS_UNSPECIFIED_FAILURE (MIH_C_STATUS_T)1 -#define MIH_C_STATUS_REJECTED (MIH_C_STATUS_T)2 -#define MIH_C_STATUS_AUTHORIZATION_FAILURE (MIH_C_STATUS_T)3 -#define MIH_C_STATUS_NETWORK_ERROR (MIH_C_STATUS_T)4 - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.3 Data types for addresses -//----------------------------------------------------------------------------- -/*! \var MIH_C_UNSIGNED_INT4_T MIH_C_CELL_ID_T -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief This data type identifies a cell uniquely within 3GPP UTRAN and -* consists of radio network controller (RNC)-ID and C-ID as defined in -* 3GPP TS 25.401. -* Valid Range: 0..268435455. -*/ -TYPEDEF_UNSIGNED_INT4(MIH_C_CELL_ID) -//------------------------------------------- -/*! -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief The BSS and cell within the BSS are identified by Cell Identity (CI). -* See 3GPP TS 23.003. -*/ -TYPEDEF_OCTET(MIH_C_CI, 2) -//------------------------------------------- -/*! -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief The public land mobile network (PLMN) unique identifier. -* PLMN_ID consists of Mobile Country Code (MCC) and Mobile Network Code (MNC). -* This is to represent the access network identifier. -* Coding of PLMN_ID is defined in 3GPP TS 25.413. -*/ -TYPEDEF_OCTET(MIH_C_PLMN_ID, 3) -//------------------------------------------- -/*! -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief Location Area Code (LAC) is a fixed length code (of 2 octets) -* identifying a location area within a public landmobile network (PLMN). -* See 3GPP TS 23.003. -*/ -TYPEDEF_OCTET(MIH_C_LAC, 2) -//------------------------------------------- -/*! \struct MIH_C_3GPP_2G_CELL_ID -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief A data type to represent a 3GPP 2G cell identifier. -*/ -typedef struct MIH_C_3GPP_2G_CELL_ID { - MIH_C_PLMN_ID_T plmn_id; - MIH_C_LAC_T lac; - MIH_C_CI_T ci; -} MIH_C_3GPP_2G_CELL_ID_T; - -//------------------------------------------- -/*! \struct MIH_C_3GPP_3G_CELL_ID -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief A data type to represent a 3GPP 3G cell identifier. -*/ -typedef struct MIH_C_3GPP_3G_CELL_ID { - MIH_C_PLMN_ID_T plmn_id; - MIH_C_CELL_ID_T cell_id; -} MIH_C_3GPP_3G_CELL_ID_T; -//------------------------------------------- -/*! \struct MIH_C_3GPP_ADDR -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief A data type to represent a 3GPP transport address. -*/ -TYPEDEF_OCTET_STRING(MIH_C_3GPP_ADDR, MIH_C_3GPP_ADDR_LENGTH) -//------------------------------------------- -/*! \struct MIH_C_3GPP2_ADDR -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief A data type to represent a 3GPP2 transport address. -*/ -TYPEDEF_OCTET_STRING(MIH_C_3GPP2_ADDR, MIH_C_3GPP2_ADDR_LENGTH) -//------------------------------------------- -/*! \var MIH_C_IANA_ADDR_T -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief Is the address family type of a transport address. -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_IANA_ADDR) -//------------------------------------------- -/*! \struct MIH_C_TRANSPORT_ADDR_T -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief A type to represent a transport address. The -* UNSIGNED_INT(2) is the address type defined in -* http://www.iana.org/assignments/address-family-numbers. -*/ -TYPEDEF_OCTET_STRING(MIH_C_TRANSPORT_ADDR_VALUE, 128) -//------------------------------------------- -#ifdef MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC_C -#define TYPEDEF_TRANSPORT_ADDR(DATA_TYPE_NAME) typedef struct DATA_TYPE_NAME {\ - MIH_C_IANA_ADDR_T address_family;\ - MIH_C_TRANSPORT_ADDR_VALUE_T address;\ - } DATA_TYPE_NAME ## _T;\ - unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* bufP) {\ - unsigned int buffer_index = 0;\ - buffer_index += sprintf(&bufP[buffer_index], "IANA = ");\ - buffer_index += MIH_C_IANA_ADDR2String(&dataP->address_family, &bufP[buffer_index]);\ - buffer_index += sprintf(&bufP[buffer_index], "TRANSPORT_ADDR = ");\ - buffer_index += MIH_C_TRANSPORT_ADDR_VALUE2String(&dataP->address, &bufP[buffer_index]);\ - return buffer_index;\ - };\ - void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_IANA_ADDR_decode(bbP, &dataP->address_family);\ - MIH_C_TRANSPORT_ADDR_VALUE_decode(bbP, &dataP->address);\ - };\ - void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP) {\ - MIH_C_IANA_ADDR_encode(bbP, &dataP->address_family);\ - MIH_C_TRANSPORT_ADDR_VALUE_encode(bbP, &dataP->address);\ - }; -#else -#define TYPEDEF_TRANSPORT_ADDR(DATA_TYPE_NAME) typedef struct DATA_TYPE_NAME {\ - MIH_C_IANA_ADDR_T address_family;\ - MIH_C_TRANSPORT_ADDR_VALUE_T address;\ - } DATA_TYPE_NAME ## _T;\ - extern unsigned int DATA_TYPE_NAME ## 2String(DATA_TYPE_NAME ## _T *dataP, char* bufP);\ - extern void DATA_TYPE_NAME ## _decode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP);\ - extern void DATA_TYPE_NAME ## _encode(Bit_Buffer_t *bbP, DATA_TYPE_NAME ## _T *dataP); -#endif -//------------------------------------------- -/*! \struct MIH_C_IP_ADDR_T -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief Represents an IP address. The Address Type is either 1 (IPv4) or 2 (IPv6). -*/ -//typedef MIH_C_TRANSPORT_ADDR_T MIH_C_IP_ADDR_T; -TYPEDEF_TRANSPORT_ADDR(MIH_C_IP_ADDR) -//------------------------------------------- -/*! \struct MIH_C_MAC_ADDR_T -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief Represents a MAC address. The Address Type contains the one used for a specific link layer. -*/ -//typedef MIH_C_TRANSPORT_ADDR_T MIH_C_MAC_ADDR_T; -TYPEDEF_TRANSPORT_ADDR(MIH_C_MAC_ADDR) -//------------------------------------------- -/*! \struct MIH_C_OTHER_L2_ADDR_T -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief A data type to represent a link-layer address other than the address already defined. -* For example, SSID. -*/ -TYPEDEF_OCTET_STRING(MIH_C_OTHER_L2_ADDR, MIH_C_OTHER_L2_ADDR_LENGTH) -//------------------------------------------- - -typedef enum { - MIH_C_CHOICE_MAC_ADDR = 0, - MIH_C_CHOICE_3GPP_3G_CELL_ID, - MIH_C_CHOICE_3GPP_2G_CELL_ID, - MIH_C_CHOICE_3GPP_ADDR, - MIH_C_CHOICE_3GPP2_ADDR, - MIH_C_CHOICE_OTHER_L2_ADDR - } MIH_C_LINK_ADDR_CHOICE_ENUM_T; -//------------------------------------------- -/*! \struct MIH_C_LINK_ADDR -* \ingroup MIH_C_F3_DATA_TYPES_FOR_ADDRESS_CODEC -* \brief A data type to represent an address of any link layer. -*/ -typedef struct MIH_C_LINK_ADDR { - MIH_C_CHOICE_T choice; - union { - MIH_C_MAC_ADDR_T mac_addr; - MIH_C_3GPP_3G_CELL_ID_T _3gpp_3g_cell_id; - MIH_C_3GPP_2G_CELL_ID_T _3gpp_2g_cell_id; - MIH_C_3GPP_ADDR_T _3gpp_addr; - MIH_C_3GPP2_ADDR_T _3gpp2_addr; - MIH_C_OTHER_L2_ADDR_T other_l2_addr; - } _union; -} MIH_C_LINK_ADDR_T; - - - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.4 Data types for links (MAINLY because of precedence definition) -//----------------------------------------------------------------------------- -/*! -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Represents percentage of battery charge remaining. - -*/ -TYPEDEF_INTEGER1(MIH_C_BATT_LEVEL) -//------------------------------------------- -/*! -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Channel identifier as defined in the specific link technology (e.g., standards -* development organization (SDO)). -* Valid Range: 0..65535 -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_CHANNEL_ID) -//------------------------------------------- -#define MIH_C_CONFIG_STATUS_SUCCESS MIH_C_BOOLEAN_TRUE -#define MIH_C_CONFIG_STATUS_ERROR MIH_C_BOOLEAN_FALSE -/*! \var MIH_C_CONFIG_STATUS_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief The status of link parameter configuration. -* TRUE: Success -* FALSE: Error -*/ -TYPEDEF_BOOLEAN(MIH_C_CONFIG_STATUS) -//------------------------------------------- -/*! \var MIH_C_DEVICE_INFO_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A non-NULL terminated string whose length shall not exceed 253 octets, representing -* information on manufacturer, model number, revision number of the software/firmware -* and serial number in displayable text. -*/ -TYPEDEF_OCTET_STRING(MIH_C_DEVICE_INFO, 253) -//------------------------------------------- -#define MIH_C_BIT_DEVICE_INFO MIH_C_BIT_0_VALUE -#define MIH_C_BIT_BATT_LEVEL MIH_C_BIT_1_VALUE -/*! -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A list of device status request. -* Bitmap Values: -* Bit 0: DEVICE_INFO -* Bit 1: BATT_LEVEL -* Bit 2–15: (Reserved) -*/ -TYPEDEF_BITMAP16(MIH_C_DEV_STATES_REQ) -//------------------------------------------- -/*! \struct MIH_C_DEV_STATE_RSP_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Represents a device status. -*/ -typedef struct MIH_C_DEV_STATE_RSP { - MIH_C_CHOICE_T choice; - union { - MIH_C_DEVICE_INFO_T device_info; - MIH_C_BATT_LEVEL_T batt_level; - } _union; -} MIH_C_DEV_STATE_RSP_T; -//------------------------------------------- -/*! -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Time (in ms) to elapse before an action needs to be taken. A value of 0 indicates -* that the action will be taken immediately. Time elapsed will be calculated from the -* instance the command arrives until the time when the execution of the action is carried out. -* Valid Range: 0..65535 -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_LINK_AC_EX_TIME) -//------------------------------------------- -/*! -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Link action result. -* 0: Success -* 1: Failure -* 2: Refused -* 3: Incapable -*/ -TYPEDEF_ENUMERATED(MIH_C_LINK_AC_RESULT) -#define MIH_C_LINK_AC_RESULT_SUCCESS (MIH_C_LINK_AC_RESULT_T)0 -#define MIH_C_LINK_AC_RESULT_FAILURE (MIH_C_LINK_AC_RESULT_T)1 -#define MIH_C_LINK_AC_RESULT_REFUSED (MIH_C_LINK_AC_RESULT_T)2 -#define MIH_C_LINK_AC_RESULT_INCAPABLE (MIH_C_LINK_AC_RESULT_T)3 -//------------------------------------------- -#define MIH_C_BIT_LINK_AC_ATTR_LINK_SCAN MIH_C_BIT_0_VALUE -#define MIH_C_BIT_LINK_AC_ATTR_LINK_RES_RETAIN MIH_C_BIT_1_VALUE -#define MIH_C_BIT_LINK_AC_ATTR_DATA_FWD_REQ MIH_C_BIT_2_VALUE -/*! -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Link action attribute that can be executed along with a valid link action. -* Detail description of each attribute is in Table F.6. -* Bitmap Values: -* Bit 0: LINK_SCAN -* Bit 1: LINK_RES_RETAIN -* Bit 2: DATA_FWD_REQ -* Bit 3–7: (Reserved) -*/ -TYPEDEF_BITMAP8(MIH_C_LINK_AC_ATTR) -//------------------------------------------- -/*! -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief An action for a link. The meaning of each link action is defined in Table F.5. -* 0: NONE -* 1: LINK_DISCONNECT -* 2: LINK_LOW_POWER -* 3: LINK_POWER_DOWN -* 4: LINK_POWER_UP -* 5–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_AC_TYPE) -#define MIH_C_LINK_AC_TYPE_NONE (MIH_C_LINK_AC_TYPE_T)0 -#define MIH_C_LINK_AC_TYPE_LINK_DISCONNECT (MIH_C_LINK_AC_TYPE_T)1 -#define MIH_C_LINK_AC_TYPE_LINK_LOW_POWER (MIH_C_LINK_AC_TYPE_T)2 -#define MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN (MIH_C_LINK_AC_TYPE_T)3 -#define MIH_C_LINK_AC_TYPE_LINK_POWER_UP (MIH_C_LINK_AC_TYPE_T)4 -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -#define MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR (MIH_C_LINK_AC_TYPE_T)5 -#define MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES (MIH_C_LINK_AC_TYPE_T)6 -#define MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES (MIH_C_LINK_AC_TYPE_T)7 -#endif -//------------------------------------------- -/*! -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Represents the link type.a -* Number assignments: -* 0: Reserved -* 1: Wireless - GSM -* 2: Wireless - GPRS -* 3: Wireless - EDGE -* 15: Ethernet -* 18: Wireless - Other -* 19: Wireless - IEEE 802.11 -* 22: Wireless - CDMA2000 -* 23: Wireless - UMTS -* 24: Wireless - cdma2000-HRPD -* 25: Wireless - LTE (MEDIEVAL) -* 27: Wireless - IEEE 802.16 -* 28: Wireless - IEEE 802.20 -* 29: Wireless - IEEE 802.22 -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_TYPE) -#define MIH_C_WIRELESS_GSM (MIH_C_LINK_TYPE_T)1 -#define MIH_C_WIRELESS_GPRS (MIH_C_LINK_TYPE_T)2 -#define MIH_C_WIRELESS_EDGE (MIH_C_LINK_TYPE_T)3 -#define MIH_C_ETHERNET (MIH_C_LINK_TYPE_T)15 -#define MIH_C_WIRELESS_OTHER (MIH_C_LINK_TYPE_T)18 -#define MIH_C_WIRELESS_IEEE802_11 (MIH_C_LINK_TYPE_T)19 -#define MIH_C_WIRELESS_CDMA_2000 (MIH_C_LINK_TYPE_T)22 -//#define MIH_C_WIRELESS_UMTS (MIH_C_LINK_TYPE_T)23 -// Temp - MW modified to test LTE for MEDIEVAL -#define MIH_C_WIRELESS_UMTS (MIH_C_LINK_TYPE_T)25 -#define MIH_C_WIRELESS_CDMA_2000_HRPD (MIH_C_LINK_TYPE_T)24 -#define MIH_C_WIRELESS_LTE (MIH_C_LINK_TYPE_T)25 -#define MIH_C_WIRELESS_IEEE802_16 (MIH_C_LINK_TYPE_T)27 -#define MIH_C_WIRELESS_IEEE802_20 (MIH_C_LINK_TYPE_T)28 -#define MIH_C_WIRELESS_IEEE802_22 (MIH_C_LINK_TYPE_T)29 -//------------------------------------------- -/*! \struct MIH_C_LINK_ID_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief The identifier of a link that is not associated with the peer node. -* The LINK_ADDR contains the address of this link. -*/ -typedef struct MIH_C_LINK_ID { - MIH_C_LINK_TYPE_T link_type; - MIH_C_LINK_ADDR_T link_addr; -} MIH_C_LINK_ID_T; -//------------------------------------------- -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -/*! \var MIH_C_PORT_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief 2 octets defining the port used by the transport protocol -*/ -TYPEDEF_OCTET(MIH_C_PORT, 2) -//------------------------------------------- -/*! \struct MIH_C_IP_TUPLE_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief Tuple consisting on an IP address and the port -*/ -typedef struct MIH_C_IP_TUPLE { - MIH_C_IP_ADDR_T ip_addr; - MIH_C_PORT_T port; -} MIH_C_IP_TUPLE_T; -//------------------------------------------- -/*! \var MIH_C_PROTO_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief The transport protocol used: -* 0: TCP -* 1: UDP -*/ -TYPEDEF_ENUMERATED(MIH_C_PROTO) -#define MIH_C_PROTO_TCP (MIH_C_PROTO_T)0 -#define MIH_C_PROTO_UDP (MIH_C_PROTO_T)1 -//------------------------------------------- -/*! \struct MIH_C_FLOW_ID_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief Five tuple, consisting on the source and destination address -* and ports plus the transport protocol used. -*/ -/*typedef struct MIH_C_FLOW_ID { - MIH_C_IP_TUPLE_T source_addr; - MIH_C_IP_TUPLE_T dest_addr; - MIH_C_PROTO_T transport_protocol; -} MIH_C_FLOW_ID_T;*/ -TYPEDEF_UNSIGNED_INT4(MIH_C_FLOW_ID) -//------------------------------------------- -/*! \struct MIH_C_MARK_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief 6 Bits (IPv4) or 20 Bits (IPv6) mask to be applied to the DSCP -* or Flow Label field of IPv4/v6 header. -*/ -typedef struct MIH_C_MARK { - MIH_C_CHOICE_T choice; - union { - BITMAP6(dscp_mask); - BITMAP20(flow_label_mask); - } _union; -} MIH_C_MARK_T; -//------------------------------------------- -/*! \var MIH_C_MAX_DELAY_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief Maximum delay supported by the flow in ms. -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_MAX_DELAY) -//------------------------------------------- -/*! \var MIH_C_BITRATE_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief A type to represent the maximum data rate in kb/s. -* Valid Range: 0 –– 2^32 – 1 - -*/ -TYPEDEF_UNSIGNED_INT4(MIH_C_BITRATE) -//------------------------------------------- -/*! \var MIH_C_JITTER_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief A type to represent the packet transfer delay jitter in ms. -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_JITTER) -//------------------------------------------- -/*! \var MIH_C_PKT_LOSS_RATE_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief A type to represent the packet loss rate. The loss rate is equal -* to the integer part of the result of multiplying --100 times the -* log10 of the ratio between the number of packets lost and the -* total number of packets transmitted. -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_PKT_LOSS_RATE) -//------------------------------------------- -/*! \var MIH_C_COS_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief COS Class to be used for queuing. -* To be filled for LTE and WLAN -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_COS) -//------------------------------------------- -/*! \var MIH_C_DROP_ELIGIBILITY_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief 0 means the frames are not eligible to discarding. -* 1 means frames are eligible for discarding. -*/ -TYPEDEF_BOOLEAN(MIH_C_DROP_ELIGIBILITY) -//------------------------------------------- -/*! \var MIH_C_MULTICAST_ENABLE_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief Identifies if a flow is multicast. -* 0: is not multicast -* 1: is multicast -*/ -TYPEDEF_BOOLEAN(MIH_C_MULTICAST_ENABLE) -//------------------------------------------- -/*! \var MIH_C_JUMBO_ENABLE_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief Identifies if JUMBO must be activated -* 0: Deactivate Jumbo -* 1: Activate Jumbo -*/ -TYPEDEF_BOOLEAN(MIH_C_JUMBO_ENABLE) -#endif -//------------------------------------------- -/*! \var MIH_C_LINK_DATA_RATE_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent the maximum data rate in kb/s. -* Valid Range: 0 – 232–1 -*/ -TYPEDEF_UNSIGNED_INT4(MIH_C_LINK_DATA_RATE) -//------------------------------------------- -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -/*! \struct MIH_C_QOS_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief The choice of delay and bitrate corresponds to a new flow being -* signalled through the MIH_SAP, the COS parameter is used after being processed by the WP3 AQM. -*/ -typedef struct MIH_C_QOS { - MIH_C_CHOICE_T choice; - union { - struct { - MIH_C_MAX_DELAY_T max_delay; - MIH_C_BITRATE_T bitrate; - MIH_C_JITTER_T jitter; - MIH_C_PKT_LOSS_RATE_T pkt_loss; - } mark_qos; - MIH_C_COS_T cos; - } _union; -} MIH_C_QOS_T; -//------------------------------------------- -/*! \struct MIH_C_RESOURCE_DESC_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief The choice of RESOURCE_DESC is used when the LINK_ACTIVATE_RESOURCES -* or DEACTIVATE action is selected in order to identify and -* configure the flow subject to action -*/ -typedef struct MIH_C_RESOURCE_DESC { - MIH_C_LINK_ID_T link_id; - MIH_C_FLOW_ID_T flow_id; - MIH_C_CHOICE_T choice_link_data_rate; - union { - MIH_C_NULL_T null_attr; - MIH_C_LINK_DATA_RATE_T link_data_rate; - } _union_link_data_rate; - MIH_C_CHOICE_T choice_qos; - union { - MIH_C_NULL_T null_attr; - MIH_C_QOS_T qos; - } _union_qos; - MIH_C_CHOICE_T choice_jumbo_enable; - union { - MIH_C_NULL_T null_attr; - MIH_C_JUMBO_ENABLE_T jumbo_enable; - } _union_jumbo_enable; - MIH_C_CHOICE_T choice_multicast_enable; - union { - MIH_C_NULL_T null_attr; - MIH_C_MULTICAST_ENABLE_T multicast_enable; - } _union_multicast_enable; -} MIH_C_RESOURCE_DESC_T; -//------------------------------------------- -/*! \struct MIH_C_FLOW_ATTRIBUTE_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief The choice of FLOW_ATTRIBUTE is used when the FLOW_ATTR action is -* selected in order to provide the mark and multicast configuration -* to be set up for the flow. -*/ -typedef struct MIH_C_FLOW_ATTRIBUTE { - MIH_C_FLOW_ID_T flow_id; - MIH_C_CHOICE_T choice_multicast_enable; - union { - MIH_C_NULL_T null_attr; - MIH_C_MULTICAST_ENABLE_T multicast_enable; - } _union_multicast_enable; - MIH_C_CHOICE_T choice_mark_qos; - union { - MIH_C_NULL_T null_attr; - struct { - MIH_C_MARK_T mark; - MIH_C_QOS_T qos; - } mark_qos; - } _union_mark_qos; - MIH_C_CHOICE_T choice_mark_drop_eligibility; - union { - MIH_C_NULL_T null_attr; - struct { - MIH_C_MARK_T mark; - MIH_C_DROP_ELIGIBILITY_T drop_eligibility; - } mark_drop_eligibility; - } _union_mark_drop_eligibility; - -} MIH_C_FLOW_ATTRIBUTE_T; -//------------------------------------------- -/*! \struct MIH_C_LINK_AC_PARAM_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief The choice of FLOW_ATTRIBUTE is used when the FLOW_ATTR action is selected -* in order to provide the mark and multicast configuration to be set up for the flow. -* The choice of RESOURCE_DESC is used when LINK_ACTIVATE_RESOURCES or -* LINK_DEACTIVATE_RESOURCES actions are used. -*/ -typedef struct MIH_C_LINK_AC_PARAM { - MIH_C_CHOICE_T choice; - union { - MIH_C_NULL_T null_attr; - MIH_C_FLOW_ATTRIBUTE_T flow_attribute; - MIH_C_RESOURCE_DESC_T resource_desc; - } _union; -} MIH_C_LINK_AC_PARAM_T; -#endif -//------------------------------------------- -/*! \struct MIH_C_LINK_ACTION_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Link action. -*/ -typedef struct MIH_C_LINK_ACTION { - MIH_C_LINK_AC_TYPE_T link_ac_type; - MIH_C_LINK_AC_ATTR_T link_ac_attr; -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - MIH_C_LINK_AC_PARAM_T link_ac_param; /*!< \brief extension of MEDIEVAL PROJECT */ -#endif -} MIH_C_LINK_ACTION_T; -//------------------------------------------- -/*! \struct MIH_C_LINK_ACTION_REQ_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A set of handover action request parameters. The choice of LINK_ADDR is to -* provide PoA address information when the LINK_ACTION contains the attribute for DATA_FWD_REQ. -*/ -typedef struct MIH_C_LINK_ACTION_REQ { - MIH_C_LINK_ID_T link_id; - MIH_C_CHOICE_T choice; - union { - MIH_C_NULL_T null_attr; - MIH_C_LINK_ADDR_T link_addr; - } _union; - - MIH_C_LINK_ACTION_T link_action; - MIH_C_LINK_AC_EX_TIME_T link_action_ex_time; -} MIH_C_LINK_ACTION_REQ_T; -//------------------------------------------- -/*! \struct MIH_C_SIG_STRENGTH_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Represents the signal strength in dBm unit or its relative value in an arbitrary percentage scale. -*/ -typedef struct MIH_C_SIG_STRENGTH { - MIH_C_CHOICE_T choice; - union { - INTEGER1(dbm) - PERCENTAGE(percentage) - } _union; -} MIH_C_SIG_STRENGTH_T; -#define MIH_C_SIG_STRENGTH_CHOICE_DBM (MIH_C_CHOICE_T)0 -#define MIH_C_SIG_STRENGTH_CHOICE_PERCENTAGE (MIH_C_CHOICE_T)1 -//------------------------------------------- -/*! \var MIH_C_NETWORK_ID_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent a network identifier. -* A non-NULL terminated string whose length shall not exceed 253 octets. -*/ -TYPEDEF_OCTET_STRING(MIH_C_NETWORK_ID, 253) -//------------------------------------------- -/*! \struct MIH_C_LINK_SCAN_RSP_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Represents a scan response. The LINK_ADDR contains the PoA link address. -* The PoA belongs to the NETWORK_ID with the given SIG_STRENGTH. -*/ -typedef struct MIH_C_LINK_SCAN_RSP { - MIH_C_LINK_ADDR_T link_addr; - MIH_C_NETWORK_ID_T network_id; - MIH_C_SIG_STRENGTH_T sig_strength; -} MIH_C_LINK_SCAN_RSP_T; -//------------------------------------------- -/*! \var MIH_C_LINK_SCAN_RSP_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_LINK_SCAN_RSP, MIH_C_LINK_SCAN_RSP_LENGTH) -//------------------------------------------- -/*! \struct MIH_C_LINK_ACTION_RSP_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A set of link action returned results. -*/ -typedef struct MIH_C_LINK_ACTION_RSP { - MIH_C_LINK_ID_T link_id; - MIH_C_LINK_AC_RESULT_T link_ac_result; - MIH_C_CHOICE_T choice; - union { - MIH_C_NULL_T null_attr; - LIST(MIH_C_LINK_SCAN_RSP, link_scan_rsp) - } _union; -} MIH_C_LINK_ACTION_RSP_T; -//------------------------------------------- -#define MIH_C_BIT_LINK_EVENT_SUBSCRIBE MIH_C_BIT_1_VALUE -#define MIH_C_BIT_LINK_EVENT_UNSUBSCRIBE MIH_C_BIT_2_VALUE -#define MIH_C_BIT_LINK_GET_PARAMETERS MIH_C_BIT_3_VALUE -#define MIH_C_BIT_LINK_CONFIGURE_THRESHOLDS MIH_C_BIT_4_VALUE -#define MIH_C_BIT_LINK_ACTION MIH_C_BIT_5_VALUE -/*! \var MIH_C_LINK_CMD_LIST_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A list of link commands. -* Bitmap Values: -* Bit 0: Reserved -* Bit 1: Link_Event_Subscribe -* Bit 2: Link_Event_Unsubscribe -* Bit 3: Link_Get_Parameters -* Bit 4: Link_Configure_Thresholds -* Bit 5: Link_Action -* Bit 6-31: (Reserved) -*/ -TYPEDEF_BITMAP32(MIH_C_LINK_CMD_LIST) -//------------------------------------------- -/*! \var MIH_C_TH_ACTION_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief -* 0: Set normal threshold -* 1: Set one-shot threshold -* 2: Cancel threshold -*/ -TYPEDEF_ENUMERATED(MIH_C_TH_ACTION) -#define MIH_C_SET_NORMAL_THRESHOLD (MIH_C_TH_ACTION_T)0 -#define MIH_C_SET_ONE_SHOT_THRESHOLD (MIH_C_TH_ACTION_T)1 -#define MIH_C_CANCEL_THRESHOLD (MIH_C_TH_ACTION_T)2 -//------------------------------------------- -/*! \var MIH_C_THRESHOLD_VAL_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Threshold value. The format of the media-dependent value is defined in the -* respective media specification standard and the equivalent number of bits (i.e., -* first bits) of this data type is used. In case that there are remaining unused bits -* in the data type, these are marked as all-zeros (‘0’). -* Valid Range: 0..65535 -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_THRESHOLD_VAL) - -//------------------------------------------- -/*! \var MIH_C_THRESHOLD_XDIR_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief The direction the threshold is to be crossed. -* 0: ABOVE_THRESHOLD -* 1: BELOW_THRESHOLD -* 2–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_THRESHOLD_XDIR) -#define MIH_C_ABOVE_THRESHOLD (MIH_C_THRESHOLD_XDIR_T)0 -#define MIH_C_BELOW_THRESHOLD (MIH_C_THRESHOLD_XDIR_T)1 -//------------------------------------------- -/*! \struct MIH_C_THRESHOLD_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A link threshold. The threshold is considered crossed when the value of the -* link parameter passes the threshold in the specified direction. -*/ -typedef struct MIH_C_THRESHOLD { - MIH_C_THRESHOLD_VAL_T threshold_val; - MIH_C_THRESHOLD_XDIR_T threshold_xdir; -} MIH_C_THRESHOLD_T; -//------------------------------------------- -/*! \var MIH_C_TIMER_INTERVAL_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief This timer value (ms) is used to set the interval between periodic reports. -* Valid Range: 0..65535 -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_TIMER_INTERVAL) -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_GEN_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent a generic link parameter that is applicable to any link type. -* 0: Data Rate—the parameter value is represented as a DATA_RATE. -* 1: Signal Strength—the parameter value is represented as a SIG_STRENGTH. -* 2: Signal over interference plus noise ratio (SINR)—the parameter value is -* represented as an UNSIGNED_INT(2). -* 3:Throughput (the number of bits successfully received divided by the time it -* took to transmit them over the medium)—the parameter value is represented as -* an UNSIGNED_INT(2). -* 4: Packet Error Rate (representing the ratio between the number of frames received -* in error and the total number of frames transmitted in a link population of interest) -* the parameter value is represented as a PERCENTAGE. -* 5–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_GEN) -#define MIH_C_LINK_PARAM_GEN_DATA_RATE (MIH_C_LINK_PARAM_GEN_T)0 -#define MIH_C_LINK_PARAM_GEN_SIGNAL_STRENGTH (MIH_C_LINK_PARAM_GEN_T)1 -#define MIH_C_LINK_PARAM_GEN_SINR (MIH_C_LINK_PARAM_GEN_T)2 -#define MIH_C_LINK_PARAM_GEN_THROUGHPUT (MIH_C_LINK_PARAM_GEN_T)3 -#define MIH_C_LINK_PARAM_GEN_PACKET_ERROR_RATE (MIH_C_LINK_PARAM_GEN_T)4 -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_QOS_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent QOS_LIST parameters. -* 0: Maximum number of differentiable classes of service supported. -* 1: Minimum packet transfer delay for all CoS, the minimum delay over a class -* population of interest. -* 2: Average packet transfer delay for all CoS, the arithmetic mean of the delay -* over a class population of interest. (See B.3.4) -* 3: Maximum packet transfer delay for all CoS, the maximum delay over a class -* population of interest. -* 4: Packet transfer delay jitter for all CoS, the standard deviation of the delay -* over a class population of interest. (See B.3.5.) -* 5: Packet loss rate for all CoS, the ratio between the number of frames that are -* transmitted but not received and the total number of frames transmitted over -* a class population of interest. (See B.3.2.) -* 6–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_QOS) -#define MIH_C_LINK_PARAM_QOS_MAX_NUM_DIF_COS_SUPPORTED (MIH_C_LINK_PARAM_QOS_T)0 -#define MIH_C_LINK_PARAM_QOS_MIN_PACKET_TRANSFER_DELAY_ALL_COS (MIH_C_LINK_PARAM_QOS_T)1 -#define MIH_C_LINK_PARAM_QOS_AVG_PACKET_TRANSFER_DELAY_ALL_COS (MIH_C_LINK_PARAM_QOS_T)2 -#define MIH_C_LINK_PARAM_QOS_MAX_PACKET_TRANSFER_DELAY_ALL_COS (MIH_C_LINK_PARAM_QOS_T)3 -#define MIH_C_LINK_PARAM_QOS_STD_DEVIATION_PACKET_TRANSFER_DELAY (MIH_C_LINK_PARAM_QOS_T)4 -#define MIH_C_LINK_PARAM_QOS_PACKET_LOSS_RATE_ALL_COS_FRAME_RATIO (MIH_C_LINK_PARAM_QOS_T)5 -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_GG_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent a link parameter for GSM and GPRS. See 3GPP TS 25.008. -* 0: RxQual -* 1: RsLev -* 2: Mean BEP -* 3: StDev BEP -* 4-255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_GG) -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_EDGE_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent a link parameter for EDGE. -* 0-255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_EDGE) -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_ETH_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent a link parameter for Ethernet. -* 0-255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_ETH) -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_802_11_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent a link parameter for IEEE 802.11. -* 0: RSSI of the beacon channel, as defined in IEEE Std 802.11-2007. -* (This is applicable only for an MN.) -* 1: No QoS resource available. The corresponding LINK_PARAM_VAL is BOOLEAN set to TRUE when -* no QoS resources available. (This applicable when the traffic stream to be transmitted -* is on an access category configured for mandatory admission control and the request for -* bandwidth was denied by the available APs in the access network). -* 2: Multicast packet loss rate. -* 3–255: (Reserved) -* Medieval extensions: -* 3: System Load. Percentage of usage load present at the system. -* 4:Number registered users. -* 5:Number active users. -* 6:Congestion window of users. Ordered list of the CW used by the clients, ordered according to -* highest value of MAC address. -* 7:Transmission rate of users. Ordered list of the transmission rate used by the clients, ordered -* according to highest value of MAC address. -* 8-255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_802_11) -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_C2K_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent a link parameter for CDMA2000. -* 0: PILOT_STRENGTH -* 1–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_C2K) -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_FDD_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent a link parameter for UMTS. See 3GPP TS 25.215. -* 0: CPICH RSCP -* 1: PCCPCH RSCP -* 2: UTRA carrier RSSI -* 3: GSM carrier RSSI -* 4: CPICH Ec/No -* 5: Transport channel BLER -* 6: user equipment (UE) transmitted power -* 7–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_FDD) -#define MIH_C_LINK_PARAM_FDD_CPICH_RSCP (MIH_C_LINK_PARAM_FDD_T)0 -#define MIH_C_LINK_PARAM_FDD_PCCPCH_RSCP (MIH_C_LINK_PARAM_FDD_T)1 -#define MIH_C_LINK_PARAM_FDD_UTRA_CARRIER_RSSI (MIH_C_LINK_PARAM_FDD_T)2 -#define MIH_C_LINK_PARAM_FDD_GSM_CARRIER_RSSI (MIH_C_LINK_PARAM_FDD_T)3 -#define MIH_C_LINK_PARAM_FDD_CPICH_EC_NO (MIH_C_LINK_PARAM_FDD_T)4 -#define MIH_C_LINK_PARAM_FDD_TRANSPORT_CHANNEL_BLER (MIH_C_LINK_PARAM_FDD_T)5 -#define MIH_C_LINK_PARAM_FDD_UE_TRANMITTED_POWER (MIH_C_LINK_PARAM_FDD_T)6 -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_HRPD_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent a link parameter for CDMA2000 HRPD. -* 0: PILOT_STRENGTH -* 1–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_HRPD) -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_802_16_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent a link parameter for IEEE 802.16. -* 0–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_802_16) -//------------------------------------------- -/*! \var MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent a link parameter for IEEE 802.20. -* 0–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_802_20) -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_802_22_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A type to represent a link parameter for IEEE 802.22. -* 0–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_802_22) -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_LTE_T -* \ingroup MIH_C_MEDIEVAL_EXTENSIONS -* \brief A type to represent a link parameter for LTE. -* -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_PARAM_LTE) -#define MIH_C_LINK_PARAM_LTE_UE_RSRP 0 -#define MIH_C_LINK_PARAM_LTE_UE_RSRQ 1 -#define MIH_C_LINK_PARAM_LTE_UE_CQI 2 -#define MIH_C_LINK_PARAM_LTE_AVAILABLE_BW 3 -#define MIH_C_LINK_PARAM_LTE_PACKET_DELAY 4 -#define MIH_C_LINK_PARAM_LTE_PACKET_LOSS_RATE 5 -#define MIH_C_LINK_PARAM_LTE_L2_BUFFER_STATUS 6 -#define MIH_C_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES 7 -#define MIH_C_LINK_PARAM_LTE_EMBMS_CAPABILITY 8 -#define MIH_C_LINK_PARAM_LTE_JUMBO_FEASIBILITY 9 -#define MIH_C_LINK_PARAM_LTE_JUMBO_SETUP_STATUS 10 -#define MIH_C_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW 11 - -//------------------------------------------- -/*! \struct MIH_C_LINK_PARAM_TYPE_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Measurable link parameter for which thresholds are being set. -*/ -#define MIH_C_LINK_PARAM_TYPE_CHOICE_GEN (MIH_C_CHOICE_T)0 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_QOS (MIH_C_CHOICE_T)1 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_GG (MIH_C_CHOICE_T)2 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_EDGE (MIH_C_CHOICE_T)3 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_ETH (MIH_C_CHOICE_T)4 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_802_11 (MIH_C_CHOICE_T)5 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_C2K (MIH_C_CHOICE_T)6 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_FDD (MIH_C_CHOICE_T)7 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_HRPD (MIH_C_CHOICE_T)8 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_802_16 (MIH_C_CHOICE_T)9 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_802_20 (MIH_C_CHOICE_T)10 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_802_22 (MIH_C_CHOICE_T)11 -#define MIH_C_LINK_PARAM_TYPE_CHOICE_LTE (MIH_C_CHOICE_T)12 - -typedef struct MIH_C_LINK_PARAM_TYPE { - MIH_C_CHOICE_T choice; - union { - MIH_C_LINK_PARAM_GEN_T link_param_gen; - MIH_C_LINK_PARAM_QOS_T link_param_qos; - MIH_C_LINK_PARAM_GG_T link_param_gg; - MIH_C_LINK_PARAM_EDGE_T link_param_edge; - MIH_C_LINK_PARAM_ETH_T link_param_eth; - MIH_C_LINK_PARAM_802_11_T link_param_802_11; - MIH_C_LINK_PARAM_C2K_T link_param_c2k; - MIH_C_LINK_PARAM_FDD_T link_param_fdd; - MIH_C_LINK_PARAM_HRPD_T link_param_hrpd; - MIH_C_LINK_PARAM_802_16_T link_param_802_16; - MIH_C_LINK_PARAM_802_20_T link_param_802_20; - MIH_C_LINK_PARAM_802_22_T link_param_802_22; - MIH_C_LINK_PARAM_LTE_T link_param_lte; - } _union; -} MIH_C_LINK_PARAM_TYPE_T; -//------------------------------------------- -/*! \var MIH_C_THRESHOLD_LIST_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_THRESHOLD, MIH_C_THRESHOLD_LIST_LENGTH) -/*! \struct MIH_C_LINK_CFG_PARAM_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A link configuration parameter. -* TH_ACTION indicates what action to apply to the listed thresholds. -* When “Cancel threshold†is selected and no thresholds are specified, then all -* currently configured thresholds for the given LINK_PARAM_TYPE are cancelled. -* When “Cancel threshold†is selected and thresholds are specified only those -* configured thresholds for the given LINK_PARAM_TYPE and whose threshold value -* match what was specified are cancelled. -* With “Set one-shot threshold†the listed thresholds are first set and then each of -* the threshold is cancelled as soon as it is crossed for the first time. -*/ -typedef struct MIH_C_LINK_CFG_PARAM { - MIH_C_LINK_PARAM_TYPE_T link_param_type; - MIH_C_CHOICE_T choice; - union { - MIH_C_NULL_T null_attr; - MIH_C_TIMER_INTERVAL_T timer_interval; -#ifdef RAL_SAME_AS_MEDIEVAL_PROJECT_BUT_I_THINK_THIS_IS_AN_ERROR - LIST(MIH_C_LINK_SCAN_RSP, link_scan_rsp) -#endif - } _union; - MIH_C_TH_ACTION_T th_action; - LIST(MIH_C_THRESHOLD, threshold) -} MIH_C_LINK_CFG_PARAM_T; -//------------------------------------------- -/*! \struct MIH_C_LINK_CFG_STATUS_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief The status of link parameter configuration for each threshold specified in the THRESHOLD. -*/ -typedef struct MIH_C_LINK_CFG_STATUS { - MIH_C_LINK_PARAM_TYPE_T link_param_type; - MIH_C_THRESHOLD_T threshold; - MIH_C_CONFIG_STATUS_T config_status; -} MIH_C_LINK_CFG_STATUS_T; -//------------------------------------------- -#define MIH_C_BIT_NUMBER_OF_CLASSES_OF_SERVICE_SUPPORTED MIH_C_BIT_0_VALUE -#define MIH_C_BIT_NUMBER_OF_QUEUES_SUPPORTED MIH_C_BIT_1_VALUE -/*! \var MIH_C_LINK_DESC_REQ_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A set of link descriptors. -* Bitmap Values: -* Bit 0: Number of Classes of Service Supported -* Bit 1: Number of Queues Supported -* Bits 2–15: (Reserved) -*/ -TYPEDEF_BITMAP16(MIH_C_LINK_DESC_REQ) -//------------------------------------------- -/*! \var MIH_C_NUM_COS_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief The maximum number of differentiable classes of service supported. -* Valid Range: 0..255 -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_NUM_COS) -//------------------------------------------- -/*! \var MIH_C_NUM_QUEUE_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief The number of transmit queues supported. -* Valid Range: 0..255 -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_NUM_QUEUE) -//------------------------------------------- -/*! \struct MIH_C_LINK_DESC_RSP_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Descriptors of a link. -*/ -typedef struct MIH_C_LINK_DESC_RSP { - MIH_C_CHOICE_T choice; - union { - MIH_C_NUM_COS_T num_cos; - MIH_C_NUM_QUEUE_T num_queue; - } _union; -} MIH_C_LINK_DESC_RSP_T; -//------------------------------------------- -/*! \var MIH_C_LINK_DN_REASON_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Represents the reason of a link down event. -* See Table F.7 for the enumeration values. -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_DN_REASON) -//------------------------------------------- -#define MIH_C_BIT_LINK_DETECTED MIH_C_BIT_0_VALUE -#define MIH_C_BIT_LINK_UP MIH_C_BIT_1_VALUE -#define MIH_C_BIT_LINK_DOWN MIH_C_BIT_2_VALUE -#define MIH_C_BIT_LINK_PARAMETERS_REPORT MIH_C_BIT_3_VALUE -#define MIH_C_BIT_LINK_GOING_DOWN MIH_C_BIT_4_VALUE -#define MIH_C_BIT_LINK_HANDOVER_IMMINENT MIH_C_BIT_5_VALUE -#define MIH_C_BIT_LINK_HANDOVER_COMPLETE MIH_C_BIT_6_VALUE -#define MIH_C_BIT_LINK_PDU_TRANSMIT_STATUS MIH_C_BIT_7_VALUE -/*! \var MIH_C_LINK_EVENT_LIST_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A list of link events. The specified event is selected if the corresponding bit is set to 1. -* Bitmap values: -* Bit 0: Link_Detected -* Bit 1: Link_Up -* Bit 2: Link_Down -* Bit 3: Link_Parameters_Report -* Bit 4: Link_Going_Down -* Bit 5: Link_Handover_Imminent -* Bit 6: Link_Handover_Complete -* Bit 7: Link_PDU_Transmit_Status -* Bit 8–31: (Reserved) -*/ -TYPEDEF_BITMAP32(MIH_C_LINK_EVENT_LIST) -//------------------------------------------- -/*! \var MIH_C_LINK_GD_REASON_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Represents the reason of a link going down. See Table F.8 for the enumeration values. -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_LINK_GD_REASON) -//------------------------------------------- -#define MIH_C_BIT_EVENT_SERVICE_SUPPORTED MIH_C_BIT_1_VALUE -#define MIH_C_BIT_COMMAND_SERVICE_SUPPORTED MIH_C_BIT_2_VALUE -#define MIH_C_BIT_INFORMATION_SERVICE_SUPPORTED MIH_C_BIT_3_VALUE -/*! \var MIH_C_LINK_MIHCAP_FLAG_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Represents if MIH capability is supported or not. If the bit is set, it indicates -* that the capability is supported. -* Bitmap values: -* Bit 1: event service (ES) supported -* Bit 2: command service (CS) supported -* Bit 3: information service (IS) supported -* Bit 0, 4–7: (Reserved) -*/ -TYPEDEF_BITMAP8(MIH_C_LINK_MIHCAP_FLAG) -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_VAL_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief The current value of the parameter. The format of the media-dependent value is defined in -* the respective media specification standard and the equivalent number of bits (i.e., first -* bits) of this data type is used. In case that there are remaining unused bits in the data -* type, these are marked as all-zeros (‘0’). -* Valid Range: 0..65535 -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_LINK_PARAM_VAL) - - - - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.9 Data types for QOS (MAINLY because of precedence definition) -//----------------------------------------------------------------------------- -//------------------------------------------- -/*! \var MIH_C_COS_ID_T -* \ingroup MIH_C_F9_DATA_TYPES_FOR_QOS -* \brief Defines MIH_C_COS_ID_T as a MIH_C_UNSIGNED_INT1_T. -* Valid Range: 0–255 -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_COS_ID) -//------------------------------------------- -/*! \struct MIH_C_MIN_PK_TX_DELAY_T -* \ingroup MIH_C_F9_DATA_TYPES_FOR_QOS -* \brief A type to represent the minimum packet transfer delay in ms for the specific CoS specified by the COS_ID. -*/ -typedef struct MIH_C_MIN_PK_TX_DELAY { - MIH_C_COS_ID_T cos_id; - UNSIGNED_INT2(value) -} MIH_C_MIN_PK_TX_DELAY_T; -//------------------------------------------- -/*! \struct MIH_C_AVG_PK_TX_DELAY_T -* \ingroup MIH_C_F9_DATA_TYPES_FOR_QOS -* \brief A type to represent the average packet transfer delay in ms for the specific CoS specified by the COS_ID. -*/ -typedef struct MIH_C_AVG_PK_TX_DELAY { - MIH_C_COS_ID_T cos_id; - UNSIGNED_INT2(value) -} MIH_C_AVG_PK_TX_DELAY_T; -//------------------------------------------- -/*! \struct MIH_C_MAX_PK_TX_DELAY_T -* \ingroup MIH_C_F9_DATA_TYPES_FOR_QOS -* \brief A type to represent the maximum packet transfer delay in ms for the specific CoS specified by the COS_ID. -*/ -typedef struct MIH_C_MAX_PK_TX_DELAY { - MIH_C_COS_ID_T cos_id; - UNSIGNED_INT2(value) -} MIH_C_MAX_PK_TX_DELAY_T; -//------------------------------------------- -/*! \struct MIH_C_PK_DELAY_JITTER_T -* \ingroup MIH_C_F9_DATA_TYPES_FOR_QOS -* \brief A type to represent the packet transfer delay jitter in ms for the specific CoS specified by the COS_ID. -*/ -typedef struct MIH_C_PK_DELAY_JITTER { - MIH_C_COS_ID_T cos_id; - UNSIGNED_INT2(value) -} MIH_C_PK_DELAY_JITTER_T; -//------------------------------------------- -/*! \struct MIH_C_PK_LOSS_RATE_T -* \ingroup MIH_C_F9_DATA_TYPES_FOR_QOS -* \brief A type to represent the packet loss rate for the specific CoS specified by the COS_ID. The loss rate is -* equal to the integer part of the result of multiplying –100 times the log10 of the ratio between the num- -* ber of packets lost and the total number of packets transmitted in the class population of interest. -*/ -typedef struct MIH_C_PK_LOSS_RATE { - MIH_C_COS_ID_T cos_id; - UNSIGNED_INT2(value) -} MIH_C_PK_LOSS_RATE_T; -//------------------------------------------- -/*! \var MIH_C_MIN_PK_TX_DELAY_LIST_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_MIN_PK_TX_DELAY, MIH_C_QOS_LIST_LENGTH) -/*! \var MIH_C_AVG_PK_TX_DELAY_LIST_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_AVG_PK_TX_DELAY, MIH_C_QOS_LIST_LENGTH) -/*! \var MIH_C_MAX_PK_TX_DELAY_LIST_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_MAX_PK_TX_DELAY, MIH_C_QOS_LIST_LENGTH) -/*! \var MIH_C_PK_DELAY_JITTER_LIST_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_PK_DELAY_JITTER, MIH_C_QOS_LIST_LENGTH) -/*! \var MIH_C_PK_LOSS_RATE_LIST_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_PK_LOSS_RATE, MIH_C_QOS_LIST_LENGTH) - -//------------------------------------------- -/*! \var MIH_C_NUM_COS_TYPES_T -* \ingroup MIH_C_F9_DATA_TYPES_FOR_QOS -* \brief -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_NUM_COS_TYPES) - -/*! \struct MIH_C_QOS_PARAM_VAL_T -* \ingroup MIH_C_F9_DATA_TYPES_FOR_QOS -* \brief A choice of Class of Service (CoS) parameters. -*/ -typedef struct MIH_C_QOS_PARAM_VAL { - MIH_C_CHOICE_T choice; - union { - MIH_C_NUM_COS_TYPES_T num_qos_types; - LIST(MIH_C_MIN_PK_TX_DELAY, min_pk_tx_delay) - LIST(MIH_C_AVG_PK_TX_DELAY, avg_pk_tx_delay) - LIST(MIH_C_MAX_PK_TX_DELAY, max_pk_tx_delay) - LIST(MIH_C_PK_DELAY_JITTER, pk_delay_jitter) - LIST(MIH_C_PK_LOSS_RATE, pk_loss_rate) - } _union; -} MIH_C_QOS_PARAM_VAL_T; -#define MIH_C_QOS_PARAM_VAL_CHOICE_NUM_QOS_TYPES (MIH_C_CHOICE_T)0 -#define MIH_C_QOS_PARAM_VAL_CHOICE_MIN_PK_TX_DELAY (MIH_C_CHOICE_T)1 -#define MIH_C_QOS_PARAM_VAL_CHOICE_AVG_PK_TX_DELAY (MIH_C_CHOICE_T)2 -#define MIH_C_QOS_PARAM_VAL_CHOICE_MAX_PK_TX_DELAY (MIH_C_CHOICE_T)3 -#define MIH_C_QOS_PARAM_VAL_CHOICE_PK_DELAY_JITTER (MIH_C_CHOICE_T)4 -#define MIH_C_QOS_PARAM_VAL_CHOICE_PK_LOSS_RATE (MIH_C_CHOICE_T)5 - -//------------------------------------------- -/*! \struct MIH_C_QOS_LIST_T -* \ingroup MIH_C_F9_DATA_TYPES_FOR_QOS -* \brief A list of Class of Service (CoS) parameters. -*/ -typedef struct MIH_C_QOS_LIST { - MIH_C_NUM_COS_TYPES_T num_qos_types; - LIST(MIH_C_MIN_PK_TX_DELAY, min_pk_tx_delay) - LIST(MIH_C_AVG_PK_TX_DELAY, avg_pk_tx_delay) - LIST(MIH_C_MAX_PK_TX_DELAY, max_pk_tx_delay) - LIST(MIH_C_PK_DELAY_JITTER, pk_delay_jitter) - LIST(MIH_C_PK_LOSS_RATE, pk_loss_rate) -} MIH_C_QOS_LIST_T; - - - -//------------------------------------------- -/*! \struct MIH_C_LINK_PARAM_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Represents a link parameter type and value pair. -*/ -typedef struct MIH_C_LINK_PARAM { - MIH_C_LINK_PARAM_TYPE_T link_param_type; - MIH_C_CHOICE_T choice; - union { - MIH_C_LINK_PARAM_VAL_T link_param_val; - MIH_C_QOS_PARAM_VAL_T qos_param_val; - } _union; -} MIH_C_LINK_PARAM_T; -#define MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL (MIH_C_CHOICE_T)0 -#define MIH_C_LINK_PARAM_CHOICE_QOS_PARAM_VAL (MIH_C_CHOICE_T)1 -//------------------------------------------- -/*! \struct MIH_C_LINK_PARAM_RPT_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Represents a link parameter report. -* Includes an option of the THRESHOLD that was crossed. -* If no THRESHOLD is included, then this is a periodic report. -*/ -typedef struct MIH_C_LINK_PARAM_RPT { - MIH_C_LINK_PARAM_T link_param; - MIH_C_CHOICE_T choice; - union { - MIH_C_NULL_T null_attr; - MIH_C_THRESHOLD_T threshold; - } _union; -} MIH_C_LINK_PARAM_RPT_T; -#define MIH_C_LINK_PARAM_RPT_CHOICE_NULL 0 -#define MIH_C_LINK_PARAM_RPT_CHOICE_THRESHOLD 1 -//------------------------------------------- -/*! \var MIH_C_LINK_ADDR_LIST_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_LINK_ADDR, MIH_C_LINK_ADDR_LIST_LENGTH) -/*! \struct MIH_C_LINK_POA_LIST_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A list of PoAs for a particular link. The LIST(LINK_ADDR) is a list of PoA -* link addresses and is sorted from most preferred first to least preferred last. -*/ -typedef struct MIH_C_LINK_POA_LIST { - MIH_C_LINK_ID_T link_id; - LIST(MIH_C_LINK_ADDR, link_addr) -} MIH_C_LINK_POA_LIST_T; -//------------------------------------------- -#define MIH_C_LINK_RES_STATUS_AVAILABLE MIH_C_MIH_C_BOOLEAN_TRUE -#define MIH_C_LINK_RES_STATUS_NOT_AVAILABLE MIH_C_BOOLEAN_FALSE -/*! \var MIH_C_LINK_RES_STATUS_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Indicates if a resource is available or not. -* TRUE: Available -* FALSE: Not available. -*/ -TYPEDEF_BOOLEAN(MIH_C_LINK_RES_STATUS) -//------------------------------------------- -#define MIH_C_BIT_LINK_STATES_REQ_OP_MODE MIH_C_BIT_0_VALUE -#define MIH_C_BIT_LINK_STATES_REQ_CHANNEL_ID MIH_C_BIT_1_VALUE -/*! \var MIH_C_LINK_STATES_REQ_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Link states to be requested. -* Bit 0: OP_MODE -* Bit 1: CHANNEL_ID -* Bit 2–15: (Reserved) -*/ -TYPEDEF_BITMAP16(MIH_C_LINK_STATES_REQ) -//------------------------------------------- -#define MIH_C_OPMODE_NORMAL_MODE 0 -#define MIH_C_OPMODE_POWER_SAVING_MODE 1 -#define MIH_C_OPMODE_POWERED_DOWN 2 -/*! \var MIH_C_OPMODE_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief The link power mode. -* 0: Normal Mode -* 1: Power Saving Mode -* 2: Powered Down -* 3–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_OPMODE) -//------------------------------------------- -/*! \struct MIH_C_LINK_STATES_RSP_T -* \brief The operation mode or the channel ID of the link. -*/ -typedef struct MIH_C_LINK_STATES_RSP { - MIH_C_CHOICE_T choice; - union { - MIH_C_OPMODE_T op_mode; - MIH_C_CHANNEL_ID_T channel_id; - } _union; -} MIH_C_LINK_STATES_RSP_T; -//------------------------------------------- -/*! \var MIH_C_LINK_PARAM_TYPE_LIST_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_LINK_PARAM_TYPE, MIH_C_LINK_STATUS_REQ_LIST_LENGTH) -/*! \struct MIH_C_LINK_STATUS_REQ_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief Represents the possible information to request from a link. -*/ -typedef struct MIH_C_LINK_STATUS_REQ { - MIH_C_LINK_STATES_REQ_T link_states_req; - LIST(MIH_C_LINK_PARAM_TYPE, link_param_type) - MIH_C_LINK_DESC_RSP_T link_desc_rsp; -} MIH_C_LINK_STATUS_REQ_T; -//------------------------------------------- -/*! \var MIH_C_LINK_STATES_RSP_LIST_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_LINK_STATES_RSP, MIH_C_LINK_STATUS_REQ_LIST_LENGTH) -/*! \var MIH_C_LINK_PARAM_LIST_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_LINK_PARAM, MIH_C_LINK_STATUS_REQ_LIST_LENGTH) -/*! \var MIH_C_LINK_DESC_RSP_LIST_T -* \brief -*/ -TYPEDEF_LIST(MIH_C_LINK_DESC_RSP, MIH_C_LINK_STATUS_REQ_LIST_LENGTH) -/*! \struct MIH_C_LINK_STATUS_RSP_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief A set of link status parameter values correspond to the LINK_STATUS_REQ. -*/ -typedef struct MIH_C_LINK_STATUS_RSP { - LIST(MIH_C_LINK_STATES_RSP, link_states_rsp) - LIST(MIH_C_LINK_PARAM, link_param) - LIST(MIH_C_LINK_DESC_RSP, link_desc_rsp) -} MIH_C_LINK_STATUS_RSP_T; -//------------------------------------------- -/*! \struct MIH_C_LINK_TUPLE_ID_T -* \ingroup MIH_C_F4_DATA_TYPES_FOR_LINKS_CODEC -* \brief The identifier of a link that is associated with a PoA. The LINK_ID contains the MN LINK_ADDR. -* The optional LINK_ADDR contains a link address of PoA. -*/ -typedef struct MIH_C_LINK_TUPLE_ID { - MIH_C_LINK_ID_T link_id; - MIH_C_CHOICE_T choice; - union { - MIH_C_NULL_T null_attr; - MIH_C_LINK_ADDR_T link_addr; - } _union; -} MIH_C_LINK_TUPLE_ID_T; -#define MIH_C_LINK_TUPLE_ID_CHOICE_NULL 0 -#define MIH_C_LINK_TUPLE_ID_CHOICE_LINK_ADDR 1 -//------------------------------------------- - - - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.5 Link actions -//----------------------------------------------------------------------------- -#define MIH_C_LINK_ACTION_LINK_NONE 0 -#define MIH_C_LINK_ACTION_LINK_LINK_DISCONNECT 1 /* Disconnect the link connection directly.*/ -#define MIH_C_LINK_ACTION_LINK_LOW_POWER 2 /* Cause the link to adjust its battery power level to be low power consumption. */ -#define MIH_C_LINK_ACTION_LINK_POWER_DOWN 3 /* Cause the link to power down and turn off the radio.*/ -#define MIH_C_LINK_ACTION_LINK_POWER_UP 4 /* Cause the link to power up and establish L2 connectivity. For UMTS link type, power up lower layers and establish PDP context. */ - - - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.6 Link action attibutes -//----------------------------------------------------------------------------- -#define MIH_C_LINK_ACTION_ATTRIBUTE_DATA_FWD_REQ 0 /* This indication requires the buffered data at the old serving PoA entity to be forwarded - * to the new target PoA entity in order to avoid data loss. This action can be taken imme- - * diately after the old serving PoS receives MIH_N2N_HO_Commit response message from the new - * target PoS, or the old serving PoS receives MIH_Net_HO_Commit response message from the MN. - * This is not valid on UMTS link type.*/ -#define MIH_C_LINK_ACTION_ATTRIBUTE_LINK_RES_RETAIN 1 /* The link will be disconnected but the resource for the link connection still remains so - * reestablishing the link connection later can be more efficient.*/ -#define MIH_C_LINK_ACTION_ATTRIBUTE_LINK_SCAN 2 /* Cause the link to perform a scan.*/ - - - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.7 Link down reason code -//----------------------------------------------------------------------------- -#define MIH_C_LINK_DOWN_REASON_EXPLICIT_DISCONNECT 0 /* The link is down because of explicit disconnect procedures initiated either by MN or network.*/ -#define MIH_C_LINK_DOWN_REASON_PACKET_TIMEOUT 1 /* The link is down because no acknowledgements were received for transmitted packets within the - * specified time limit.*/ -#define MIH_C_LINK_DOWN_REASON_NO_RESOURCE 2 /* The link is down because there were no resources to maintain the connection.*/ -#define MIH_C_LINK_DOWN_REASON_NO_BROADCAST 3 /* The link is down because broadcast messages (such as beacons in IEEE 802.11 management frames) - * could not be received by MN. */ -#define MIH_C_LINK_DOWN_REASON_AUTHENTICATION_FAILURE 4 /* Authentication failure.*/ -#define MIH_C_LINK_DOWN_REASON_BILLING_FAILURE 5 /* Billing failure.*/ - - - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.8 Link going down reason code -//----------------------------------------------------------------------------- -#define MIH_C_LINK_GOING_DOWN_REASON_EXPLICIT_DISCONNECT 0 /* The link is going to be down because explicit disconnect procedures will be - * initiated either by MN or network. For example, when a BS has decided to - * shutdown for administrative reasons or an operator of the terminal has - * decided to execute a handover manually, a Link_Going_Down trigger is sent - * to the MIHF. - */ -#define MIH_C_LINK_GOING_DOWN_REASON_LINK_PARAMETER_DEGRADING 1 /* The link is going to be down because broadcast messages (such as beacons in - * IEEE 802.11 management frames) could not be received by MN. - */ -#define MIH_C_LINK_GOING_DOWN_REASON_LOW_POWER 2 /* The link is going to be down because the power level of the terminal is low - * and the current link will not be maintained in such a low power level. Mobile - * terminals usually have limited battery supply, and when the battery level of - * the terminal is low, a terminal can choose a link that has lower power con- - * sumption for handover according to the received Link_Going_Down triggers - * with this reason code. This will lengthen the usable time for the terminal. - */ -#define MIH_C_LINK_GOING_DOWN_REASON_NO_RESOURCE 3 /* The link is going to be down because there will be no resources to maintain - * the current connection. For example, a BS that has too many users can send - * Link_Going_Down indications to terminals when the links with them can not - * be kept because of insufficient resources. Another example is that users with - * higher priority can preempt the ones with lower priority when no more - * resources can be allocated in 3GPP, and this can also cause a - * Link_Going_Down indication with this reason code. - */ - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.10 Not implemented -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.11 Not implemented -//----------------------------------------------------------------------------- - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.12 Data types for IP configuration -//----------------------------------------------------------------------------- -#define MIH_C_BIT_IP_CFG_MTHDS_IPV4_STATIC_CONFIGURATION MIH_C_BIT_0_VALUE -#define MIH_C_BIT_IP_CFG_MTHDS_IPV4_DYNAMIC_CONFIGURATION MIH_C_BIT_1_VALUE -#define MIH_C_BIT_IP_CFG_MTHDS_MOBILE_IPV4_WITH_FA_COA MIH_C_BIT_2_VALUE -#define MIH_C_BIT_IP_CFG_MTHDS_MOBILE_IPV4_WITHOUT_FA MIH_C_BIT_3_VALUE -#define MIH_C_BIT_IP_CFG_MTHDS_IPV6_STATELESS_ADDRESS_CONFIGURATION MIH_C_BIT_11_VALUE -#define MIH_C_BIT_IP_CFG_MTHDS_IPV6_STATEFULL_ADDRESS_CONFIGURATION MIH_C_BIT_12_VALUE -#define MIH_C_BIT_IP_CFG_MTHDS_IPV6_MANUAL_ADDRESS_CONFIGURATION MIH_C_BIT_13_VALUE -/*! \var MIH_C_IP_CFG_MTHDS_T -* \brief A set of IP configuration methods. -* Bit 0: IPv4 static configuration -* Bit 1: IPv4 dynamic configuration (DHCPv4) -* Bit 2: Mobile IPv4 with foreign agent (FA) care-of address (CoA) (FA-CoA) -* Bit 3: Mobile IPv4 without FA (Co-located CoA) -* Bits 4–10: reserved for IPv4 address configurations -* Bit 11: IPv6 stateless address configuration -* Bit 12: IPv6 stateful address configuration (DHCPv6) -* Bit 13: IPv6 manual configuration -* Bits 14–31: (Reserved) -*/ -TYPEDEF_BITMAP32(MIH_C_IP_CFG_MTHDS) -//------------------------------------------- -#define MIH_C_BIT_IP_MOB_MGMT_MOBILE_IPV4 MIH_C_BIT_0_VALUE -#define MIH_C_BIT_IP_MOB_MGMT_MOBILE_IPV4_REGIONAL_REGISTRATION MIH_C_BIT_1_VALUE -#define MIH_C_BIT_IP_MOB_MGMT_MOBILE_IPV6 MIH_C_BIT_2_VALUE -#define MIH_C_BIT_IP_MOB_MGMT_HIERARCHICAL_MOBILE_IPV6 MIH_C_BIT_3_VALUE -#define MIH_C_BIT_IP_MOB_MGMT_LOW_LATENCY_HANDOFFS MIH_C_BIT_4_VALUE -#define MIH_C_BIT_IP_MOB_MGMT_MOBILE_IPV6_FAST_HANDOVERS MIH_C_BIT_5_VALUE -#define MIH_C_BIT_IP_MOB_MGMT_IKEV2_MOBILITY_AND_MULTIHOMING_PROTOCOL MIH_C_BIT_6_VALUE -/*! \var MIH_C_IP_MOB_MGMT_T -* \brief Indicates the supported mobility management protocols. -* Bit 0: Mobile IPv4 (IETF RFC 3344) -* Bit 1: Mobile IPv4 Regional Registration (IETF RFC 4857) -* Bit 2: Mobile IPv6 (IETF RFC 3775) -* Bit 3: Hierarchical Mobile IPv6 (IETF RFC 4140) -* Bit 4: Low Latency Handoffs (IETF RFC 4881) -* Bit 5: Mobile IPv6 Fast Handovers (IETF RFC 5268) -* Bit 6: IKEv2 Mobility and Multihoming Protocol (IETF RFC 4555) -* Bit 7–15: (Reserved) -*/ -TYPEDEF_BITMAP16(MIH_C_IP_MOB_MGMT) -//------------------------------------------- -/*! \var MIH_C_IP_PREFIX_LEN_T -* \brief The length of an IP subnet prefix. -* Valid Range: -* 0..32 for IPv4 subnet. -* 0..64, 65..127 for IPv6 subnet. (IETF RFC 4291 [B25]) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_IP_PREFIX_LEN) -//------------------------------------------- -/*! \var MIH_C_IP_RENEWAL_FLAG_T -* \brief Indicates whether MN’s IP address needs to be changed or not. -* TRUE: Change required. -* FALSE: Change not required. -*/ -TYPEDEF_BOOLEAN(MIH_C_IP_RENEWAL_FLAG) -//------------------------------------------- -/*! \struct MIH_C_IP_SUBNET_INFO_T -* \brief Represent an IP subnet. The IP_PREFIX_LEN contains the bit -* length of the prefix of the subnet to which the IP_ADDR -* belongs. -*/ -typedef struct MIH_C_IP_SUBNET_INFO { - MIH_C_IP_PREFIX_LEN_T ip_prefix_len; - MIH_C_IP_ADDR_T ip_addr; -} MIH_C_IP_SUBNET_INFO_T; - - - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.13 Data types for information elements -//----------------------------------------------------------------------------- -/*! \var MIH_C_NET_AUX_ID_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent an auxiliary access network -* identifier. This is HESSID if network type is -* IEEE 802.11. -*/ -TYPEDEF_OCTET_STRING(MIH_C_NET_AUX_ID, 253) - -// already defined in other section TYPEDEF_OCTET_STRING(MIH_C_NETWORK_ID, 253) -/*! \var MIH_C_BAND_CLASS_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief CDMA band class. -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_BAND_CLASS) -/*! \var MIH_C_BANDWIDTH_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief Channel bandwidth in kb/s. -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_BANDWIDTH) -/*! \var MIH_C_BASE_ID_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief Base station identifier. -*/ -TYPEDEF_UNSIGNED_INT2(MIH_C_BASE_ID) -/*! \var MIH_C_DOWN_BP_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A List of FEC Code Type for Downlink burst. -* Refer to 11.4.1 in IEEE 802.16Rev2/D5.0. -*/ -TYPEDEF_BITMAP256(MIH_C_DOWN_BP) -/*! \var MIH_C_TYPE_EXT_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A generic type extension contained indicating a flexible length and format field. The content is to be -* defined and filled by the appropriate SDO or service provider consortium, etc. -* The value is a non-NULL terminated string whose length shall not exceed 253 octets. -*/ -TYPEDEF_OCTET_STRING(MIH_C_TYPE_EXT, 253) -/*! \var MIH_C_UP_BP_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A List of FEC Code Type for Uplink burst. -* Refer to 11.3.1 in IEEE 802.16Rev2/D5.0 -*/ -TYPEDEF_BITMAP256(MIH_C_UP_BP) -//------------------------------------------- -/*! \struct MIH_C_BURST_PROF_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief Burst profile. -*/ -typedef struct MIH_C_BURST_PROF { - MIH_C_DOWN_BP_T down_bp; - MIH_C_UP_BP_T up_bp; -} MIH_C_BURST_PROF_T; -//------------------------------------------- -/*! \struct MIH_C_CH_RANGE_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type that contains two numbers. The first unsigned -* integer is the low range. The second unsigned integer -* is the high range. Both values are in kHz. -* The first unsigned integer value should always be less -* than or equal to the second unsigned integer. -*/ -typedef struct MIH_C_CH_RANGE { - UNSIGNED_INT4(low_range); - UNSIGNED_INT4(high_range); -} MIH_C_CH_RANGE_T; -//------------------------------------------- -#define MIH_C_COST_UNIT_SECOND 0 -#define MIH_C_COST_UNIT_MINUTE 1 -#define MIH_C_COST_UNIT_HOURS 2 -#define MIH_C_COST_UNIT_DAY 3 -#define MIH_C_COST_UNIT_WEEK 4 -#define MIH_C_COST_UNIT_MONTH 5 -#define MIH_C_COST_UNIT_YEAR 6 -#define MIH_C_COST_UNIT_FREE 7 -#define MIH_C_COST_UNIT_FLAT_RATE 8 -/*! \var MIH_C_COST_UNIT_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent the unit of a cost. -* 0: second -* 1: minute -* 2: hours -* 3: day -* 4: week -* 5: month -* 6: year -* 7: free -* 8: flat rate -* 9–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_COST_UNIT) -//------------------------------------------- -/*! \struct MIH_C_COST_VALUE_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent the value of a cost. -* The first 4-octet contains the integer part of the cost. -* The last 2-octet contains the fraction part where it rep- -* resents a 3-digit fraction. -* Therefore, the value range of the fraction part is -* [0,999]. -* For example, for a value of ““0.5”â€, the integer part is -* zero and the fraction part is 500. -*/ -typedef struct MIH_C_COST_VALUE { - UNSIGNED_INT4(cost_integer_part); - UNSIGNED_INT2(cost_fraction_part); -} MIH_C_COST_VALUE_T; -//------------------------------------------- -/*! \var MIH_C_COST_CURR_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent the currency of a cost. -* A three-letter currency code (e.g., “USDâ€) specified -* by ISO 4217. -*/ -TYPEDEF_OCTET_STRING(MIH_C_COST_CURR, 3) -//------------------------------------------- -/*! \struct MIH_C_COST_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent a cost. -*/ -typedef struct MIH_C_COST { - MIH_C_COST_UNIT_T cost_unit; - MIH_C_COST_VALUE_T cost_value; - MIH_C_COST_CURR_T cost_curr; -} MIH_C_COST_T; -//------------------------------------------- -/*! \var MIH_C_CNTRY_CODE_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief Country code, represented as two letter ISO 3166-1 country code in capital ASCII letters. -*/ -TYPEDEF_OCTET(MIH_C_CNTRY_CODE, 2) -//------------------------------------------- -/*! \var MIH_C_DATA_RATE_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief -*/ -TYPEDEF_UNSIGNED_INT4(MIH_C_DATA_RATE) -//------------------------------------------- -/*! \var MIH_C_DU_CTR_FREQ_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief Downlink/Uplink center frequency in kHz. -*/ -TYPEDEF_INTEGER8(MIH_C_DU_CTR_FREQ) -//------------------------------------------- -/*! \var MIH_C_EIRP_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief BS’s effective isotropic radiated power level. Signed in units of 1 dBm. -*/ -TYPEDEF_INTEGER4(MIH_C_EIRP) -//------------------------------------------- -/*! \struct MIH_C_GAP_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief This gap is an integer number of physical slot durations and starts on a -* physical slot boundary. Used on TDD systems only. -* The UNSIGNED_INT(2) is used for the TTG - transmit/receive transition gap. -* The UNSIGNED_INT(1) is used for the RTG - receive/transmit transition gap. -*/ -typedef struct MIH_C_GAP - { - UNSIGNED_INT2(ttg); - UNSIGNED_INT1(rtg); -} MIH_C_GAP_T; -//------------------------------------------- -/*! \var MIH_C_HO_CODE_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief HANDOVER_RANGING_CODE. -* Refer to 11.3.1 in IEEE 802.16Rev2/D5.0. -*/ -TYPEDEF_INTEGER1(MIH_C_HO_CODE) -//------------------------------------------- -/*! \var MIH_C_INIT_CODE_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief INITIAL_RANGING_CODE. -* Refer to 11.3.1 in IEEE 802.16Rev2/D5.0. -*/ -TYPEDEF_INTEGER1(MIH_C_INIT_CODE) -//------------------------------------------- -/*! \struct MIH_C_CDMA_CODES_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A set of CDMA ranging codes. -*/ -typedef struct MIH_C_CDMA_CODES { - MIH_C_INIT_CODE_T init_code; - MIH_C_HO_CODE_T ho_code; -} MIH_C_CDMA_CODES_T; -//------------------------------------------- -/*! \struct MIH_C_DCD_UCD_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent the downlink channel descriptor and the uplink channel descriptor. -*/ -typedef struct MIH_C_DCD_UCD { - MIH_C_BASE_ID_T base_id; - MIH_C_BANDWIDTH_T bandwidth; - MIH_C_DU_CTR_FREQ_T du_ctr_freq; - MIH_C_EIRP_T eirp; - MIH_C_GAP_T gap; - MIH_C_BURST_PROF_T burst_prof; - MIH_C_CDMA_CODES_T cdma_codes; -} MIH_C_DCD_UCD_T; -//------------------------------------------- -/*! \var MIH_C_FQDN_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief The fully qualified domain name of a host as described in IETF RFC 2181. -*/ -TYPEDEF_OCTET_STRING(MIH_C_FQDN, 253) -//------------------------------------------- -// TBD FREQ_BANDS -/*! \var MIH_C_FREQ_ID_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief Identifier of the carrier frequency. Valid Range: 0..65535 -*/ -TYPEDEF_INTEGER2(MIH_C_FREQ_ID) -//------------------------------------------- -/*! \var MIH_C_FQ_CODE_NUM_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief UMTS scrambling code, cdma2000 Walsh code. -* Valid Range: 0..65535 -*/ -TYPEDEF_INTEGER2(MIH_C_FQ_CODE_NUM) -//------------------------------------------- -/*! \var MIH_C_IP4_ADDR_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief An IPv4 address as described in IETF RFC 791 -*/ -TYPEDEF_OCTET(MIH_C_IP4_ADDR, 4) -/*! \var MIH_C_IP6_ADDR_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief An IPv6 address as described in IETF RFC 4291 -*/ -TYPEDEF_OCTET(MIH_C_IP6_ADDR, 16) - -/*! \var MIH_C_DHCP_SERV_T -* \ingroup MIH_C_F22_DATA_TYPE_FOR_HANDOVER_OPERATION -* \brief IP address of candidate DHCP Server. It is only -* included when dynamic address configuration is supported. -*/ -typedef MIH_C_IP_ADDR_T MIH_C_DHCP_SERV_T; -/*! \var MIH_C_FN_AGNT_T -* \ingroup MIH_C_F22_DATA_TYPE_FOR_HANDOVER_OPERATION -* \brief IP address of candidate Foreign Agent. It is only included when Mobile IPv4 is supported. -*/ -typedef MIH_C_IP_ADDR_T MIH_C_FN_AGNT_T; -/*! \var MIH_C_ACC_RTR_T -* \ingroup MIH_C_F22_DATA_TYPE_FOR_HANDOVER_OPERATION -* \brief IP address of candidate Access Router. It is only -* included when IPv6 Stateless configuration is supported. -*/ -typedef MIH_C_IP_ADDR_T MIH_C_ACC_RTR_T; -//------------------------------------------- -/*! \struct MIH_C_IP_CONFIG_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief IP Configuration Methods supported by the access network. -*/ -typedef struct MIH_C_IP_CONFIG - { - MIH_C_IP_CFG_MTHDS_T ip_cfg_mthds; - MIH_C_CHOICE_T choice_dhcp_serv; - union { - MIH_C_NULL_T null_attr; - MIH_C_DHCP_SERV_T dhcp_serv; - } _union_dhcp_serv; - MIH_C_CHOICE_T choice_fn_agnt; - union { - MIH_C_NULL_T null_attr; - MIH_C_FN_AGNT_T fn_agnt; - } _union_fn_agnt; - MIH_C_CHOICE_T choice_acc_rtr; - union { - MIH_C_NULL_T null_attr; - MIH_C_ACC_RTR_T acc_rtr; - } _union_acc_rtr; -} MIH_C_IP_CONFIG_T; -//------------------------------------------- -#define MIH_C_BIT_NET_CAPS_SECURITY MIH_C_BIT_0_VALUE -#define MIH_C_BIT_NET_CAPS_QOS_CLASS0 MIH_C_BIT_1_VALUE -#define MIH_C_BIT_NET_CAPS_QOS_CLASS1 MIH_C_BIT_2_VALUE -#define MIH_C_BIT_NET_CAPS_QOS_CLASS2 MIH_C_BIT_3_VALUE -#define MIH_C_BIT_NET_CAPS_QOS_CLASS3 MIH_C_BIT_4_VALUE -#define MIH_C_BIT_NET_CAPS_QOS_CLASS4 MIH_C_BIT_5_VALUE -#define MIH_C_BIT_NET_CAPS_QOS_CLASS5 MIH_C_BIT_6_VALUE -#define MIH_C_BIT_NET_CAPS_INTERNET_ACCESS MIH_C_BIT_7_VALUE -#define MIH_C_BIT_NET_CAPS_EMERGENCY_SERVICES MIH_C_BIT_8_VALUE -#define MIH_C_BIT_NET_CAPS_MIH_CAPABILITY MIH_C_BIT_9_VALUE -/*! \var MIH_C_NET_CAPS_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief These bits provide high level capabilities supported on a network. -* Bitmap Values: -* Bit 0: Security – Indicates that some level of security is supported when set. -* Bit 1: QoS Class 0 – Indicates that QoS for class 0 is supported when set. -* Bit 2: QoS Class 1 – Indicates that QoS for class 1 is supported when set. -* Bit 3: QoS Class 2 – Indicates that QoS for class 2 is supported when set; Otherwise, no QoS for class 2 support is available. -* Bit 4: QoS Class 3 – Indicates that QoS for class 3 is supported when set; Otherwise, no QoS for class 3 support is available. -* Bit 5: QoS Class 4 – Indicates that QoS for class 4 is supported when set; Otherwise, no QoS for class 4 support is available. -* Bit 6: QoS Class 5 – Indicates that QoS for class 5 is supported when set; Otherwise, no QoS for class 5 support is available. -* Bit 7: Internet Access – Indicates that Internet access is supported when set; Otherwise, no Internet access support is available. -* Bit 8: Emergency Services – Indicates that some level of emergency services is supported when set; Otherwise, no emergency service support is available. -* Bit 9: MIH Capability – Indicates that MIH is supported when set; Otherwise, no MIH support is available. -* Bit 10–31: (Reserved) -*/ -TYPEDEF_BITMAP32(MIH_C_NET_CAPS) -//------------------------------------------- -/*! \var MIH_C_SUBTYPE_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A network subtype. See Table F.14. -*/ -TYPEDEF_BITMAP64(MIH_C_SUBTYPE) -//------------------------------------------- - -//------------------------------------------- -/*! \struct MIH_C_NETWORK_TYPE_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent a network type and its subtype. -* See Table F.14 for details. -*/ -typedef struct MIH_C_NETWORK_TYPE - { - MIH_C_CHOICE_T choice_link_type; - union { - MIH_C_NULL_T null_attr; - MIH_C_LINK_TYPE_T link_type; - } _union_link_type; - MIH_C_CHOICE_T choice_subtype; - union { - MIH_C_NULL_T null_attr; - MIH_C_SUBTYPE_T subtype; - } _union_subtype; - MIH_C_CHOICE_T choice_type_ext; - union { - MIH_C_NULL_T null_attr; - MIH_C_TYPE_EXT_T type_ext; - } _union_type_ext; -} MIH_C_NETWORK_TYPE_T; -//------------------------------------------- -/*! \var MIH_C_OP_NAME_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent an operator name. The value -* uniquely identifies the operator name within the scope -* of the OP_NAMESPACE. -* The value is a non NULL terminated string whose -* length shall not exceed 253 octets. -*/ -TYPEDEF_OCTET_STRING(MIH_C_OP_NAME, 253) -//------------------------------------------- -/*! \var MIH_C_OP_NAMESPACE_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent a type of operator name. -* 0: GSM/UMTS -* 1: CDMA -* 2: REALM (as defined in [B28]). -* 3: ITU-T/TSB -* 4: General -* 5–255: (Reserved) -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_OP_NAMESPACE) -//------------------------------------------- -/*! \struct MIH_C_OPERATOR_ID_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent an operator identifier. -*/ -typedef struct MIH_C_OPERATOR_ID { - MIH_C_OP_NAME_T opname; - MIH_C_OP_NAMESPACE_T opnamespace; -} MIH_C_OPERATOR_ID_T; -//------------------------------------------- -/*! \struct MIH_C_SIB_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A type to represent UMTS system information block (SIB). -*/ -typedef struct MIH_C_SIB { - MIH_C_CELL_ID_T cell_id; - MIH_C_FQ_CODE_NUM_T fq_code_num; -} MIH_C_SIB_T; -//------------------------------------------- -/*! \var MIH_C_PILOT_PN_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief Pilot PN sequence offset index. -*/ -TYPEDEF_INTEGER2(MIH_C_PILOT_PN) -//------------------------------------------- -/*! \struct MIH_C_SYS_PARAMS_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief CDMA2000 system parameters. -*/ -typedef struct MIH_C_SYS_PARAMS { - MIH_C_BASE_ID_T base_id; - MIH_C_PILOT_PN_T pilot_pn; - MIH_C_FREQ_ID_T freq_id; - MIH_C_BAND_CLASS_T band_class; -} MIH_C_SYS_PARAMS_T; -//------------------------------------------- -/*! \struct MIH_C_MIH_C_PARAMETERS_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A data type to represent system information depending on the network type. -* DCD_UCD: IEEE 802.16 -* SIB: UMTS -* SYS_PARAMS: cdma2000 -*/ -typedef struct MIH_C_PARAMETERS { - MIH_C_CHOICE_T choice; - union { - MIH_C_DCD_UCD_T dcd_ucd; - MIH_C_SIB_T sib; - MIH_C_SYS_PARAMS_T sys_params; - } _union; -} MIH_C_MIH_C_PARAMETERS_T; -//------------------------------------------- -/*! \struct MIH_C_PROXY_ADDR_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief L3 address of a proxy server. -*/ -typedef struct MIH_C_PROXY_ADDR { - MIH_C_CHOICE_T choice; - union { - MIH_C_IP4_ADDR_T ip4_addr; - MIH_C_IP6_ADDR_T ip6_addr; - MIH_C_FQDN_T fqdn; - } _union; -} MIH_C_PROXY_ADDR_T; -//------------------------------------------- -// TBD REGU_DOMAIN -// TBD ROAMING_PTNS -/*! \var MIH_C_SP_ID_T -* \ingroup MIH_C_F13_DATA_TYPES_FOR_INFORMATION_ELEMENTS -* \brief A service provider identifier. -* A non-NULL terminated string whose length shall not exceed 253 octets. -*/ -TYPEDEF_OCTET_STRING(MIH_C_SP_ID, 253) -// TBD SUPPORTED_LCP -// TBD SYSTEM_INFO - - - - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.19 Data type for MIHF identification -//----------------------------------------------------------------------------- -/** \defgroup MIH_C_F19_DATA_TYPE_FOR_MIHF_IDENTIFICATION Data types for MIHF identification - * \ingroup MIH_C_INTERFACE - * - * @{ - */ -/*! \var MIH_C_MIHF_ID_T -* \brief The MIHF Identifier: MIHF_ID is a network access identifier (NAI). -* NAI shall be unique as per IETF RFC 4282. If L3 communication is -* used and MIHF entity resides in the network node, then MIHF_ID is -* the fully qualified domain name or NAI-encoded IP address -* (IP4_ADDR or IP6_ADDR) of the entity that hosts the MIH Services. -* If L2 communication is used then MIHF_ID is the NAI-encoded link- -* layer address (LINK_ADDR) of the entity that hosts the MIH ser- -* vices. In an NAI-encoded IP address or link-layer address, each octet -* of binary-encoded IP4_ADDR, IP6_ADDR and LINK_ADDR data is -* encoded in the username part of the NAI as “\†followed by the octet -* value. A multicast MIHF identifier is defined as an MIHF ID of zero -* length. When an MIH protocol message with multicast MIHF ID is -* transmitted over the L2 data plane, a group MAC address (01-80-C2- -* 00-00-0E) shall be used (see IEEE P802.1aj/D2.2). The maximum -* length is 253 octets. -*/ -TYPEDEF_OCTET_STRING(MIH_C_MIHF_ID, 253) -/** @}*/ - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.20—Data type for MIH capabilities -//----------------------------------------------------------------------------- -/** \defgroup MIH_C_F19_DATA_TYPE_FOR_MIHF_CAPABILITIES Data type for MIH capabilities - * \ingroup MIH_C_INTERFACE - * - * @{ - */ -/*! \struct MIH_C_LINK_DET_CFG_T -* \brief A data type for configuring link detected event trigger. -*/ -typedef struct MIH_C_LINK_DET_CFG { - MIH_C_CHOICE_T choice_network_id; - union { - MIH_C_NULL_T null_attr; - MIH_C_NETWORK_ID_T network_id; - } _union_network_id; - MIH_C_CHOICE_T choice_sig_strength; - union { - MIH_C_NULL_T null_attr; - MIH_C_SIG_STRENGTH_T sig_strength; - } _union_sig_strength; - MIH_C_CHOICE_T choice_link_data_rate; - union { - MIH_C_NULL_T null_attr; - MIH_C_LINK_DATA_RATE_T link_data_rate; - } _union_link_data_rate; -} MIH_C_LINK_DET_CFG_T; -//------------------------------------------- -/*! \struct MIH_C_EVT_CFG_INFO_T -* \brief Represents additional configuration information -* for event subscription. The list of -* LINK_DET_CFG contains additional filtering -* when subscribing to link detected events. The list -* of LINK_CFG_PARAM contains additional fil- -* tering when subscribing to link parameter report -* events. -*/ -typedef struct MIH_C_EVT_CFG_INFO { - MIH_C_CHOICE_T choice; - union { - MIH_C_LINK_DET_CFG_T link_det_cfg; - MIH_C_LINK_CFG_PARAM_T link_cfg_param; - } _union; -} MIH_C_EVT_CFG_INFO_T; -//------------------------------------------- -/*! \struct MIH_C_LINK_DET_INFO_T -* \brief Information of a detected link. -* LINK_TUPLE_ID is the link detected. -* NETWORK_ID is the access network identifier. -* NET_AUX_ID is an auxiliary access network identifier if applicable. -* SIG_STRENGTH is the signal strength of the detected link. -* UNSIGNED_INT(2) is the SINR value of the link. -* LINK_DATA_RATE is the maximum transmission rate on the detected link. -* LINK_MIHCAP_FLAG indicates which MIH capabilities are supported on the detected link. -* NET_CAPS is the network capability supported by the network link. -*/ -typedef struct MIH_C_LINK_DET_INFO { - MIH_C_LINK_TUPLE_ID_T link_tuple_id; - MIH_C_NETWORK_ID_T network_id; - MIH_C_NET_AUX_ID_T net_aux_id; - MIH_C_SIG_STRENGTH_T sig_strength; - UNSIGNED_INT2(sinr) - MIH_C_LINK_DATA_RATE_T link_data_rate; - MIH_C_LINK_MIHCAP_FLAG_T link_mihcap_flag; - MIH_C_NET_CAPS_T net_caps; -} MIH_C_LINK_DET_INFO_T; -//------------------------------------------- -/*! \struct MIH_C_MBB_HO_SUPP_T -* \brief Indicates if make before break is supported FROM the first network type TO the second network type. -* The BOOLEAN value assignment: -* True: Make before break is supported. -* False: Make before break is not supported. -*/ -typedef struct MIH_C_MBB_HO_SUPP { - MIH_C_NETWORK_TYPE_T from; - MIH_C_NETWORK_TYPE_T to; - BOOLEAN(supported) -} MIH_C_MBB_HO_SUPP_T; -//------------------------------------------- -#define MIH_C_BIT_MIH_CMD_MIH_LINK_GET_PARAMETERS MIH_C_BIT_0_VALUE -#define MIH_C_BIT_MIH_CMD_MIH_LINK_CONFIGURE_THRESHOLDS MIH_C_BIT_1_VALUE -#define MIH_C_BIT_MIH_CMD_MIH_LINK_ACTIONS MIH_C_BIT_2_VALUE -#define MIH_C_BIT_MIH_CMD_MIH_NET_HO_CANDIDATE_QUERY MIH_C_BIT_3_VALUE -#define MIH_C_BIT_MIH_CMD_MIH_NET_HO_COMMIT MIH_C_BIT_3_VALUE -#define MIH_C_BIT_MIH_CMD_MIH_N2N_HO_QUERY_RESOURCES MIH_C_BIT_3_VALUE -#define MIH_C_BIT_MIH_CMD_MIH_N2N_HO_COMMIT MIH_C_BIT_3_VALUE -#define MIH_C_BIT_MIH_CMD_MIH_N2N_HO_COMPLETE MIH_C_BIT_3_VALUE -#define MIH_C_BIT_MIH_CMD_MIH_MN_HO_CANDIDATE_QUERY MIH_C_BIT_4_VALUE -#define MIH_C_BIT_MIH_CMD_MIH_MN_HO_COMMIT MIH_C_BIT_4_VALUE -#define MIH_C_BIT_MIH_CMD_MIH_MN_HO_COMPLETE MIH_C_BIT_4_VALUE - -/*! \var MIH_C_MIH_CMD_LIST_T -* \brief A list of MIH commands. -* Bitmap Values: -* Bit 0: MIH_Link_Get_Parameters -* Bit 1: MIH_Link_Configure_Thresholds -* Bit 2: MIH_Link_Actions -* Bit 3: MIH_Net_HO_Candidate_Query -* MIH_Net_HO_Commit -* MIH_N2N_HO_Query_Resources -* MIH_N2N_HO_Commit -* MIH_N2N_HO_Complete -* Bit 4: MIH_MN_HO_Candidate_Query -* MIH_MN_HO_Commit -* MIH_MN_HO_Complete -* Bit 5–31: (Reserved) - -*/ -TYPEDEF_BITMAP32(MIH_C_MIH_CMD_LIST) - -//------------------------------------------- -#define MIH_C_BIT_MIH_LINK_DETECTED MIH_C_BIT_0_VALUE -#define MIH_C_BIT_MIH_LINK_UP MIH_C_BIT_1_VALUE -#define MIH_C_BIT_MIH_LINK_DOWN MIH_C_BIT_2_VALUE -#define MIH_C_BIT_MIH_LINK_PARAMETERS_REPORT MIH_C_BIT_3_VALUE -#define MIH_C_BIT_MIH_LINK_GOING_DOWN MIH_C_BIT_4_VALUE -#define MIH_C_BIT_MIH_LINK_HANDOVER_IMMINENT MIH_C_BIT_5_VALUE -#define MIH_C_BIT_MIH_LINK_HANDOVER_COMPLETE MIH_C_BIT_6_VALUE -#define MIH_C_BIT_MIH_LINK_PDU_TRANSMIT_STATUS MIH_C_BIT_7_VALUE -/*! \var MIH_C_MIH_EVT_LIST_T -* \brief A list of MIH events. -* Bitmap Values: -* Bit 0: MIH_Link_Detected -* Bit 1: MIH_Link_Up -* Bit 2: MIH_Link_Down -* Bit 3: MIH_Link_Parameters_Report -* Bit 4: MIH_Link_Going_Down -* Bit 5: MIH_Link_Handover_Imminent -* Bit 6: MIH_Link_Handover_Complete -* Bit 7: MIH_Link_PDU_Transmit_Status -* Bit 8–31: (Reserved) -*/ -TYPEDEF_BITMAP32(MIH_C_MIH_EVT_LIST) -//------------------------------------------- -#define MIH_C_BIT_BINARY_DATA MIH_C_BIT_0_VALUE -#define MIH_C_BIT_RDF_DATA MIH_C_BIT_1_VALUE -#define MIH_C_BIT_RDF_SCHEMA_URL MIH_C_BIT_2_VALUE -#define MIH_C_BIT_RDF_SCHEMA MIH_C_BIT_3_VALUE -#define MIH_C_BIT_IE_NETWORK_TYPE MIH_C_BIT_4_VALUE -#define MIH_C_BIT_IE_OPERATOR_ID MIH_C_BIT_5_VALUE -#define MIH_C_BIT_IE_SERVICE_PROVIDER_ID MIH_C_BIT_6_VALUE -#define MIH_C_BIT_IE_COUNTRY_CODE MIH_C_BIT_7_VALUE -#define MIH_C_BIT_IE_NETWORK_ID MIH_C_BIT_8_VALUE -#define MIH_C_BIT_IE_NETWORK_AUX_ID MIH_C_BIT_9_VALUE -#define MIH_C_BIT_IE_ROAMING_PARTNERS MIH_C_BIT_10_VALUE -#define MIH_C_BIT_IE_COST MIH_C_BIT_11_VALUE -#define MIH_C_BIT_IE_NETWORK_QOS MIH_C_BIT_12_VALUE -#define MIH_C_BIT_IE_NETWORK_DATA_RATE MIH_C_BIT_13_VALUE -#define MIH_C_BIT_IE_NET_REGULT_DOMAIN MIH_C_BIT_14_VALUE -#define MIH_C_BIT_IE_NET_FREQUENCY_BANDS MIH_C_BIT_15_VALUE -#define MIH_C_BIT_IE_NET_IP_CFG_METHODS MIH_C_BIT_16_VALUE -#define MIH_C_BIT_IE_NET_CAPABILITIES MIH_C_BIT_17_VALUE -#define MIH_C_BIT_IE_NET_SUPPORTED_LCP MIH_C_BIT_18_VALUE -#define MIH_C_BIT_IE_NET_MOB_MGMT_PROT MIH_C_BIT_19_VALUE -#define MIH_C_BIT_IE_NET_EMSERV_PROXY MIH_C_BIT_20_VALUE -#define MIH_C_BIT_IE_NET_IMS_PROXY_CSCF MIH_C_BIT_21_VALUE -#define MIH_C_BIT_IE_NET_MOBILE_NETWORK MIH_C_BIT_22_VALUE -#define MIH_C_BIT_IE_POA_LINK_ADDR MIH_C_BIT_23_VALUE -#define MIH_C_BIT_IE_POA_LOCATION MIH_C_BIT_24_VALUE -#define MIH_C_BIT_IE_POA_CHANNEL_RANGE MIH_C_BIT_25_VALUE -#define MIH_C_BIT_IE_POA_SYSTEM_INFO MIH_C_BIT_26_VALUE -#define MIH_C_BIT_IE_POA_SUBNET_INFO MIH_C_BIT_27_VALUE -#define MIH_C_BIT_IE_POA_IP_ADDR MIH_C_BIT_28_VALUE -/*! \var MIH_C_MIH_IQ_TYPE_LST_T -* \brief A list of IS query types. -* Bitmap Values: -* Bit 0: Binary data -* Bit 1: RDF data -* Bit 2: RDF schema URL -* Bit 3: RDF schema -* Bit 4: IE_NETWORK_TYPE -* Bit 5: IE_OPERATOR_ID -* Bit 6: IE_SERVICE_PROVIDER_ID -* Bit 7: IE_COUNTRY_CODE -* Bit 8: IE_NETWORK_ID -* Bit 9: IE_NETWORK_AUX_ID -* Bit 10: IE_ROAMING_PARTNERS -* Bit 11: IE_COST -* Bit 12: IE_NETWORK_QOS -* Bit 13: IE_NETWORK_DATA_RATE -* Bit 14: IE_NET_REGULT_DOMAIN -* Bit 15: IE_NET_FREQUENCY_BANDS -* Bit 16: IE_NET_IP_CFG_METHODS -* Bit 17: IE_NET_CAPABILITIES -* Bit 18: IE_NET_SUPPORTED_LCP -* Bit 19: IE_NET_MOB_MGMT_PROT -* Bit 20: IE_NET_EMSERV_PROXY -* Bit 21: IE_NET_IMS_PROXY_CSCF -* Bit 22: IE_NET_MOBILE_NETWORK -* Bit 23: IE_POA_LINK_ADDR -* Bit 24: IE_POA_LOCATION -* Bit 25: IE_POA_CHANNEL_RANGE -* Bit 26: IE_POA_SYSTEM_INFO -* Bit 27: IE_POA_SUBNET_INFO -* Bit 28: IE_POA_IP_ADDR -* Bit 29–63: (Reserved) -*/ -TYPEDEF_BITMAP64(MIH_C_MIH_IQ_TYPE_LST) -//------------------------------------------- -#define MIH_C_BIT_UDP MIH_C_BIT_0_VALUE -#define MIH_C_BIT_TCP MIH_C_BIT_1_VALUE -/*! \var MIH_C_MIH_TRANS_LST_T -* \brief A list of supported transports. -* Bitmap Values: -* Bit 0: UDP -* Bit 1: TCP -* Bit 2–15: (Reserved) -*/ -TYPEDEF_BITMAP16(MIH_C_MIH_TRANS_LST) -//------------------------------------------- -/*! \struct MIH_C_NET_TYPE_ADDR_T -* \brief Represent a link address of a specific network type. -*/ -typedef struct MIH_C_NET_TYPE_ADDR { - MIH_C_NETWORK_TYPE_T network_type; - MIH_C_LINK_ADDR_T link_addr; -} MIH_C_NET_TYPE_ADDR_T; -//------------------------------------------- -/** @}*/ - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.22—Data types for handover operation -//----------------------------------------------------------------------------- -/** \defgroup MIH_C_F22_DATA_TYPE_FOR_HANDOVER_OPERATION Data type for handover operation - * \ingroup MIH_C_INTERFACE - * - * @{ - */ -//TBD ASGN_RES_SET -/*! \var MIH_C_HO_CAUSE_T -* \brief Represents the reason for performing a handover. -* Same enumeration list as link down reason code. -* See Table F.7 -*/ -TYPEDEF_UNSIGNED_INT1(MIH_C_HO_CAUSE) -//------------------------------------------- -/*! \var MIH_C_HO_RESULT_T -* \brief Handover result. -* 0: Success -* 1: Failure -* 2: Rejected -*/ -TYPEDEF_ENUMERATED(MIH_C_HO_RESULT) -#define MIH_C_HO_RESULT_SUCCESS (MIH_C_HO_RESULT_T)0 -#define MIH_C_HO_RESULT_FAILURE (MIH_C_HO_RESULT_T)1 -#define MIH_C_HO_RESULT_REJECTED (MIH_C_HO_RESULT_T)2 -//------------------------------------------- -/*! \var MIH_C_HO_STATUS_T -* \brief Represents the permission for handover. -* 0: HandoverPermitted -* 1: HandoverDeclined -*/ -TYPEDEF_ENUMERATED(MIH_C_HO_STATUS) -#define MIH_C_HO_STATUS_HANDOVER_PERMITTED (MIH_C_HO_STATUS_T)0 -#define MIH_C_HO_STATUS_HANDOVER_DECLINED (MIH_C_HO_STATUS_T)1 -//------------------------------------------- -/*! \var MIH_C_PREDEF_CFG_ID_T -* \brief Pre-defined configuration identifier. -* 0..255 -*/ -TYPEDEF_INTEGER1(MIH_C_PREDEF_CFG_ID) -//------------------------------------------- -//TBD RQ_RESULT -//TBD REQ_RES_SET -//TBD TGT_NET_INFO -//TBD TSP_CARRIER -//TBD TSP_CONTAINER -/** @}*/ - - -//----------------------------------------------------------------------------- -// STD 802.21-2008 Table F.23—Data type for MIH_NET_SAP primitives -//----------------------------------------------------------------------------- -/** \defgroup MIH_C_F23_DATA_TYPE_FOR_MIH_NET_SAP_PRIMITIVES Data type for MIH NET SAP primitives. - * \ingroup MIH_C_INTERFACE - * - * @{ - */ -/*! \var MIH_C_TRANSPORT_TYPE_T -* \brief The transport type supported: -* 0: L2 -* 1: L3 or higher layer protocols -*/ -TYPEDEF_ENUMERATED(MIH_C_TRANSPORT_TYPE) -#define MIH_C_TRANSPORT_TYPE_L2 (MIH_C_TRANSPORT_TYPE_T)0 -#define MIH_C_TRANSPORT_TYPE_L3_OR_HIGHER_PROTOCOLS (MIH_C_TRANSPORT_TYPE_T)1 - -/** @}*/ - - - - -/** - * \ingroup MIH_C_INTERFACE - * - * @{ - */ - -#define MIH_C_TLV_SOURCE_MIHF_ID (MIH_C_INTEGER1_T)1 -#define MIH_C_TLV_DESTINATION_MIHF_ID (MIH_C_INTEGER1_T)2 -#define MIH_C_TLV_STATUS (MIH_C_INTEGER1_T)3 -#define MIH_C_TLV_LINK_TYPE (MIH_C_INTEGER1_T)4 -#define MIH_C_TLV_MIH_EVENT_LIST (MIH_C_INTEGER1_T)5 -#define MIH_C_TLV_MIH_COMMAND_LIST (MIH_C_INTEGER1_T)6 -#define MIH_C_TLV_MIIS_QUERY_TYPE_LIST (MIH_C_INTEGER1_T)7 -#define MIH_C_TLV_TRANSPORT_OPTION_LIST (MIH_C_INTEGER1_T)8 -#define MIH_C_TLV_LINK_ADDRESS_LIST (MIH_C_INTEGER1_T)9 -#define MIH_C_TLV_MBB_HANDOVER_SUPPORT (MIH_C_INTEGER1_T)10 -#define MIH_C_TLV_REGISTER_REQUEST_CODE (MIH_C_INTEGER1_T)11 -#define MIH_C_TLV_VALID_TIME_INTERVAL (MIH_C_INTEGER1_T)12 -#define MIH_C_TLV_LINK_IDENTIFIER (MIH_C_INTEGER1_T)13 -#define MIH_C_TLV_NEW_LINK_IDENTIFIER (MIH_C_INTEGER1_T)14 -#define MIH_C_TLV_OLD_ACCESS_ROUTER (MIH_C_INTEGER1_T)15 -#define MIH_C_TLV_NEW_ACCESS_ROUTER (MIH_C_INTEGER1_T)16 -#define MIH_C_TLV_IP_RENEWAL_FLAG (MIH_C_INTEGER1_T)17 -#define MIH_C_TLV_MOBILITY_MANAGEMENT_SUPPORT (MIH_C_INTEGER1_T)18 -#define MIH_C_TLV_IP_ADDRESS_CONFIGURATION_METHODS (MIH_C_INTEGER1_T)19 -#define MIH_C_TLV_LINK_DOWN_REASON_CODE (MIH_C_INTEGER1_T)20 -#define MIH_C_TLV_LINK_TIME_INTERVAL (MIH_C_INTEGER1_T)21 -#define MIH_C_TLV_LINK_GOING_DOWN_REASON_CODE (MIH_C_INTEGER1_T)22 -#define MIH_C_TLV_LINK_PARAMETER_REPORT_LIST (MIH_C_INTEGER1_T)23 -#define MIH_C_TLV_DEVICE_STATES_REQUEST (MIH_C_INTEGER1_T)24 -#define MIH_C_TLV_LINK_IDENTIFIER_LIST (MIH_C_INTEGER1_T)25 -#define MIH_C_TLV_DEVICE_STATES_RESPONSE_LIST (MIH_C_INTEGER1_T)26 -#define MIH_C_TLV_GET_STATUS_REQUEST_SET (MIH_C_INTEGER1_T)27 -#define MIH_C_TLV_GET_STATUS_RESPONSE_LIST (MIH_C_INTEGER1_T)28 -#define MIH_C_TLV_CONFIGURE_REQUEST_LIST (MIH_C_INTEGER1_T)29 -#define MIH_C_TLV_CONFIGURE_RESPONSE_LIST (MIH_C_INTEGER1_T)30 -#define MIH_C_TLV_LIST_OF_LINK_POA_LIST (MIH_C_INTEGER1_T)31 -#define MIH_C_TLV_PREFERRED_LINK_LIST (MIH_C_INTEGER1_T)32 -#define MIH_C_TLV_HANDOVER_RESOURCE_QUERY_LIST (MIH_C_INTEGER1_T)33 -#define MIH_C_TLV_HANDOVER_STATUS (MIH_C_INTEGER1_T)34 -#define MIH_C_TLV_ACCESS_ROUTER_ADDRESS (MIH_C_INTEGER1_T)35 -#define MIH_C_TLV_DHCP_SERVER_ADDRESS (MIH_C_INTEGER1_T)36 -#define MIH_C_TLV_FA_ADDRESS (MIH_C_INTEGER1_T)37 -#define MIH_C_TLV_LINK_ACTIONS_LIST (MIH_C_INTEGER1_T)38 -#define MIH_C_TLV_LINK_ACTIONS_RESULT_LIST (MIH_C_INTEGER1_T)39 -#define MIH_C_TLV_HANDOVER_RESULT (MIH_C_INTEGER1_T)40 -#define MIH_C_TLV_RESOURCE_STATUS (MIH_C_INTEGER1_T)41 -#define MIH_C_TLV_RESOURCE_RETENTION_STATUS (MIH_C_INTEGER1_T)42 -#define MIH_C_TLV_INFO_QUERY_BINARY_DATA_LIST (MIH_C_INTEGER1_T)43 -#define MIH_C_TLV_INFO_QUERY_RDF_DATA_LIST (MIH_C_INTEGER1_T)44 -#define MIH_C_TLV_INFO_QUERY_RDF_SCHEMA_URL (MIH_C_INTEGER1_T)45 -#define MIH_C_TLV_INFO_QUERY_RDF_SCHEMA_LIST (MIH_C_INTEGER1_T)46 -#define MIH_C_TLV_MAX_RESPONSE_SIZE (MIH_C_INTEGER1_T)47 -#define MIH_C_TLV_INFO_RESPONSE_BINARY_DATA_LIST (MIH_C_INTEGER1_T)48 -#define MIH_C_TLV_INFO_RESPONSE_RDF_DATA_LIST (MIH_C_INTEGER1_T)49 -#define MIH_C_TLV_INFO_RESPONSE_RDF_SCHEMA_URL_LIST (MIH_C_INTEGER1_T)50 -#define MIH_C_TLV_INFO_RESPONSE_RDF_SCHEMA_LIST (MIH_C_INTEGER1_T)51 -#define MIH_C_TLV_MOBILE_NODE_MIHF_ID (MIH_C_INTEGER1_T)52 -#define MIH_C_TLV_QUERY_RESOURCE_REPORT_FLAG (MIH_C_INTEGER1_T)53 -#define MIH_C_TLV_EVENT_CONFIGURATION_INFO_LIST (MIH_C_INTEGER1_T)54 -#define MIH_C_TLV_TARGET_NETWORK_INFO (MIH_C_INTEGER1_T)55 -#define MIH_C_TLV_LIST_OF_TARGET_NETWORK_INFO (MIH_C_INTEGER1_T)56 -#define MIH_C_TLV_ASSIGNED_RESOURCE_SET (MIH_C_INTEGER1_T)57 -#define MIH_C_TLV_LINK_DETECTED_INFO_LIST (MIH_C_INTEGER1_T)58 -#define MIH_C_TLV_MN_LINK_ID (MIH_C_INTEGER1_T)59 -#define MIH_C_TLV_POA (MIH_C_INTEGER1_T)60 -#define MIH_C_TLV_UNAUTHENTICATED_INFORMATION_REQUEST (MIH_C_INTEGER1_T)61 -#define MIH_C_TLV_NETWORK_TYPE (MIH_C_INTEGER1_T)62 -#define MIH_C_TLV_REQUESTED_RESOURCE_SET (MIH_C_INTEGER1_T)63 - -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -# define MIH_C_TLV_LINK_EVENT_LIST (MIH_C_INTEGER1_T)101 -# define MIH_C_TLV_LINK_CMD_LIST (MIH_C_INTEGER1_T)102 -# define MIH_C_TLV_LINK_PARAM_TYPE_LIST (MIH_C_INTEGER1_T)103 -# define MIH_C_TLV_LINK_PARAMETERS_STATUS_LIST (MIH_C_INTEGER1_T)104 -# define MIH_C_TLV_LINK_STATES_REQ (MIH_C_INTEGER1_T)105 -# define MIH_C_TLV_LINK_STATES_RSP_LIST (MIH_C_INTEGER1_T)106 -# define MIH_C_TLV_LINK_DESC_REQ (MIH_C_INTEGER1_T)107 -# define MIH_C_TLV_LINK_DESC_RSP_LIST (MIH_C_INTEGER1_T)108 -# define MIH_C_TLV_LINK_ACTION (MIH_C_INTEGER1_T)109 -# define MIH_C_TLV_LINK_AC_RESULT (MIH_C_INTEGER1_T)110 -# define MIH_C_TLV_LINK_SCAN_RSP_LIST (MIH_C_INTEGER1_T)111 -# define MIH_C_TLV_LINK_DET_INFO (MIH_C_INTEGER1_T)112 -# define MIH_C_TLV_LINK_INTERFACE_TYPE_ADDR (MIH_C_INTEGER1_T)113 -# define MIH_C_TLV_MOS_DSCV (MIH_C_INTEGER1_T)114 -#endif -/** @}*/ - -//----------------------------------------------------------------------------- -#endif diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_bit_buffer.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_bit_buffer.h deleted file mode 100755 index efdf84b727..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_bit_buffer.h +++ /dev/null @@ -1,151 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_bit_buffer.h - * \brief This file defines the prototypes of the functions for coding and decoding of bit fields. - * \author GAUTHIER Lionel - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MIH_C_BIT_BUFFER_H__ -# define __MIH_C_BIT_BUFFER_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_BIT_BUFFER_C -# define private_bit_buffer(x) x -# define protected_bit_buffer(x) x -# define public_bit_buffer(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_bit_buffer(x) -# define protected_bit_buffer(x) extern x -# define public_bit_buffer(x) extern x -# else -# define private_bit_buffer(x) -# define protected_bit_buffer(x) -# define public_bit_buffer(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <sys/types.h> -//----------------------------------------------------------------------------- -#define BIT_BUFFER_FALSE 0 -#define BIT_BUFFER_TRUE 1 -typedef struct BitBuffer { - unsigned int m_buffer_allocated_by_this; - u_int8_t *m_buffer; - // size allocated for buffer - unsigned int m_capacity; - - // amount of bytes written - unsigned int m_limit; - unsigned int m_byte_position; - unsigned int m_bit_mod_8_position; - -} Bit_Buffer_t; - -//----------------------------------------------------------------------------- -public_bit_buffer(Bit_Buffer_t* new_BitBuffer_0(void);) - -public_bit_buffer(Bit_Buffer_t* new_BitBuffer_1(unsigned int capacityP);) - -public_bit_buffer(Bit_Buffer_t* new_BitBuffer_2(unsigned char* bufferP, unsigned int capacityP);) - -public_bit_buffer(void BitBuffer_wrap(Bit_Buffer_t* bbP, unsigned char* bufferP, unsigned int capacityP);) - -public_bit_buffer(u_int32_t BitBuffer_read32(Bit_Buffer_t* bbP);) - -public_bit_buffer(u_int32_t BitBuffer_read32littleendian(Bit_Buffer_t* bbP);) - -public_bit_buffer(u_int16_t BitBuffer_read16(Bit_Buffer_t* bbP);) - -public_bit_buffer(u_int16_t BitBuffer_read16littleendian(Bit_Buffer_t* bbP);) - -public_bit_buffer(u_int8_t BitBuffer_read8(Bit_Buffer_t* bbP);) - -public_bit_buffer(u_int8_t BitBuffer_readBool(Bit_Buffer_t* bbP);) - -public_bit_buffer(u_int32_t BitBuffer_read(Bit_Buffer_t* bbP, const unsigned int nb_bitsP);) - -public_bit_buffer(u_int32_t BitBuffer_readlittleendian(Bit_Buffer_t* bbP, const unsigned int nb_bitsP);) - -public_bit_buffer(void BitBuffer_readMem(Bit_Buffer_t* bbP, u_int8_t* destP, unsigned int nb_bytesP);) - - -public_bit_buffer(void BitBuffer_write32(Bit_Buffer_t* bbP, u_int32_t valueP);) - -public_bit_buffer(void BitBuffer_write32littleendian(Bit_Buffer_t* bbP, u_int32_t valueP);) - -public_bit_buffer(void BitBuffer_write16littleendian(Bit_Buffer_t* bbP, u_int16_t valueP);) - -public_bit_buffer(void BitBuffer_write16(Bit_Buffer_t* bbP, u_int16_t valueP);) - -public_bit_buffer(void BitBuffer_write8(Bit_Buffer_t* bbP, u_int8_t valueP);) - -public_bit_buffer(void BitBuffer_writeBool(Bit_Buffer_t* bbP, u_int8_t valueP);) - -public_bit_buffer(void BitBuffer_writeMem(Bit_Buffer_t* bbP, u_int8_t* startP, unsigned int nb_bytesP);) - -public_bit_buffer(void BitBuffer_write8b(Bit_Buffer_t* bbP, u_int8_t valueP, unsigned int nb_bitsP);) - -public_bit_buffer(void BitBuffer_writelittleendian(Bit_Buffer_t* bbP, u_int8_t valueP, unsigned int nb_bitsP);) - -public_bit_buffer(void BitBuffer_write16b(Bit_Buffer_t* bbP, u_int16_t valueP, unsigned int nb_bitsP);) - -public_bit_buffer(void BitBuffer_writelittleendian16b(Bit_Buffer_t* bbP, u_int16_t valueP, unsigned int nb_bitsP);) - -public_bit_buffer(void BitBuffer_write32b(Bit_Buffer_t* bbP, u_int32_t valueP, unsigned int nb_bitsP);) - -public_bit_buffer(void BitBuffer_writelittleendian32b(Bit_Buffer_t* bbP, u_int32_t valueP, unsigned int nb_bitsP);) - -public_bit_buffer(void BitBuffer_rewind(Bit_Buffer_t* bbP);) - -public_bit_buffer(void BitBuffer_rewind_to(Bit_Buffer_t* bbP, unsigned int byte_positionP);) - -public_bit_buffer(void BitBuffer_write_shift_last_n_bytes_right(Bit_Buffer_t* bbP, unsigned int nb_bytes_to_shiftP, unsigned int hole_sizeP);) - -public_bit_buffer(void BitBuffer_reset(Bit_Buffer_t* bbP);) - -public_bit_buffer(unsigned char* BitBuffer_getNextFreePosition(Bit_Buffer_t* bbP);) - -public_bit_buffer(unsigned int BitBuffer_getPosition(Bit_Buffer_t* bbP);) - -public_bit_buffer(void BitBuffer_addLimitOffset(Bit_Buffer_t* bbP, unsigned int offsetP);) - -public_bit_buffer(unsigned int BitBuffer_getNumFreeBytes(Bit_Buffer_t* bbP);) - -public_bit_buffer(u_int8_t BitBuffer_isCheckWriteOverflowOK(Bit_Buffer_t* bbP, unsigned int nb_bitsP);) - -public_bit_buffer(u_int8_t BitBuffer_isCheckReadOverflowOK(Bit_Buffer_t* bbP, unsigned int nb_bitsP);) - -public_bit_buffer(void free_BitBuffer(Bit_Buffer_t* bbP);) - -#endif diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_header_codec.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_header_codec.h deleted file mode 100755 index 3b35e202bf..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_header_codec.h +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_header_codec.h - * \brief This file defines the prototypes of the functions for coding and decoding of MIH header messages. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MIH_C_HEADER_CODEC_H__ -# define __MIH_C_HEADER_CODEC_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_HEADER_CODEC_C -# define private_header_codec(x) x -# define protected_header_codec(x) x -# define public_header_codec(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_header_codec(x) -# define protected_header_codec(x) extern x -# define public_header_codec(x) extern x -# else -# define private_header_codec(x) -# define protected_header_codec(x) -# define public_header_codec(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -//#include <netdb.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/time.h> -#include <ctype.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <getopt.h> -#include <libgen.h> -//----------------------------------------------------------------------------- -#include "MIH_C_bit_buffer.h" -#include "MIH_C_Types.h" -//----------------------------------------------------------------------------- -#define MIH_HEADER_ENCODE_OK 0 -#define MIH_HEADER_DECODE_OK 0 -#define MIH_HEADER_ENCODE_TOO_SHORT -1 -#define MIH_HEADER_DECODE_TOO_SHORT -1 -#define MIH_HEADER_ENCODE_FAILURE -2 -#define MIH_HEADER_DECODE_FAILURE -2 -#define MIH_HEADER_ENCODE_BAD_PARAMETER -3 -#define MIH_HEADER_DECODE_BAD_PARAMETER -3 - -TYPEDEF_INTEGER1(MIH_C_VERSION); -TYPEDEF_INTEGER1(MIH_C_ACK_REQ); -TYPEDEF_INTEGER1(MIH_C_ACK_RSP); -TYPEDEF_INTEGER1(MIH_C_UIR); -TYPEDEF_INTEGER1(MIH_C_M); -TYPEDEF_INTEGER1(MIH_C_FN); -TYPEDEF_INTEGER1(MIH_C_SID); -TYPEDEF_INTEGER1(MIH_C_OPCODE); -TYPEDEF_INTEGER2(MIH_C_AID); -TYPEDEF_INTEGER2(MIH_C_TRANSACTION_ID); -TYPEDEF_INTEGER2(MIH_C_VARIABLE_PAYLOAD_LENGTH); -TYPEDEF_INTEGER1(MIH_C_TLV_TYPE); - - -/*! \struct MIH_C_HEADER -* \brief Structure defining the header of messages exchanged between MIH entities. -*/ -typedef struct MIH_C_HEADER { - MIH_C_VERSION_T version; - MIH_C_ACK_REQ_T ack_req; - MIH_C_ACK_RSP_T ack_rsp; - MIH_C_UIR_T uir; - MIH_C_M_T more_fragment; - MIH_C_FN_T fragment_number; - MIH_C_SID_T service_identifier; - MIH_C_OPCODE_T operation_code; - MIH_C_AID_T action_identifier; - MIH_C_TRANSACTION_ID_T transaction_id; - MIH_C_VARIABLE_PAYLOAD_LENGTH_T payload_length; -} MIH_C_HEADER_T; -//----------------------------------------------------------------------------- -public_header_codec(int MIH_C_HEADER2String(MIH_C_HEADER_T* headerP, char* bufP);) -public_header_codec(int MIH_C_Link_Header_Encode(Bit_Buffer_t* message_serializedP, MIH_C_HEADER_T* headerP);) -public_header_codec(int MIH_C_Link_Header_Decode(Bit_Buffer_t* message_serializedP, MIH_C_HEADER_T* headerP);) -//----------------------------------------------------------------------------- -#endif diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_log.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_log.h deleted file mode 100755 index aa193d0856..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_log.h +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_log.h -* \brief This file defines the prototypes of the functions for logging. -* \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle -* \date 2012 -* \version -* \note -* \bug -* \warning -*/ -#error "To be removed" -#ifndef __MIH_C_LOG_H__ -# define __MIH_C_LOG_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_LOG_C -# define private_mih_c_log(x) x -# define protected_mih_c_log(x) x -# define public_mih_c_log(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_mih_c_log(x) -# define protected_mih_c_log(x) extern x -# define public_mih_c_log(x) extern x -# else -# define private_mih_c_log(x) -# define protected_mih_c_log(x) -# define public_mih_c_log(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <syslog.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <time.h> -#include <sys/types.h> -//----------------------------------------------------------------------------- -#define LOG_CONST 0 -#define LOG_TO_CONSOLE 0 -#define LOG_TO_FILE 1 -#define LOG_TO_SYSTEM 2 -//default value -#define LOG_TO_DEFAULT LOG_TO_CONSOLE - -#define MIH_C_LOGFILE_NAME "/tmp/MIH_C_log.txt" -#define MIH_C_SYSLOG_NAME "LTE" -#define MIH_C_VERSION "1.0" //Release date : see readme - -#define EMERG(args...) MIH_C_log_record( (LOG_EMERG), ##args) -#define ALERT(args...) MIH_C_log_record( (LOG_ALERT), ##args) -#define CRIT(args...) MIH_C_log_record( (LOG_CRIT), ##args) -#define ERR(args...) MIH_C_log_record( (LOG_ERR), ##args) -#define WARNING(args...) MIH_C_log_record( (LOG_WARNING), ##args) -#define NOTICE(args...) MIH_C_log_record( (LOG_NOTICE), ##args) -#define INFO(args...) MIH_C_log_record( (LOG_INFO), ##args) -#define DEBUG(args...) MIH_C_log_record( (LOG_DEBUG), ##args) -//----------------------------------------------------------------------------- - -private_mih_c_log(FILE *g_mih_c_log_file;) - -private_mih_c_log(int g_mih_c_log_output;) - -private_mih_c_log(const char* g_log_level2string[LOG_DEBUG+1];) - -/*! \fn char* getTimeStamp4Log(void) -* \brief Get a formated string of current time. -* \return a char string of current time in seconds and micro seconds. -*/ -public_mih_c_log( char* getTimeStamp4Log(void);) - - -/*! \fn int mih_c_log_init(unsigned int log_outputP) -* \brief Initialize log module. -* \param[in] log_outputP Identifier of output where logs go are sent. -*/ -protected_mih_c_log( int MIH_C_log_init(unsigned int log_outputP);) - -/*! \fn int MIH_C_log_record(unsigned int levelP, char * log_msgP, ...) -* \brief Set log parameters. -* \param[in] levelP Level of log (ERROR, DEBUG). -* \param[in] log_msgP Message to log. -*/ -public_mih_c_log( int MIH_C_log_record(int level, const char * log_msg, ...);) - -/*! \fn int MIH_C_log_exit(void) -* \brief Close, and clean properly the log module. -*/ -protected_mih_c_log( int MIH_C_log_exit(void);) -#endif - - - - - - - - - diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_msg_codec.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_msg_codec.h deleted file mode 100755 index 0e5390af00..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_msg_codec.h +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * - * Eurecom OpenAirInterface 3 - * Copyright(c) 2012 Eurecom - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * The full GNU General Public License is included in this distribution in - * the file called "COPYING". - * - * Contact Information - * Openair Admin: openair_admin@eurecom.fr - * Openair Tech : openair_tech@eurecom.fr - * Forums : http://forums.eurecom.fsr/openairinterface - * Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France - * - *******************************************************************************/ -/*! \file MIH_C_msg_codec.h - * \brief This file defines the prototypes of the functions for coding and decoding of MIH Link messages. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MIH_C_MSG_CODEC_H__ -# define __MIH_C_MSG_CODEC_H__ -//----------------------------------------------------------------------------- -# ifdef MIH_C_MSG_CODEC_C -# define private_mih_c_msg_codec(x) x -# define protected_mih_c_msg_codec(x) x -# define public_mih_c_msg_codec(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_mih_c_msg_codec(x) -# define protected_mih_c_msg_codec(x) extern x -# define public_mih_c_msg_codec(x) extern x -# else -# define private_mih_c_msg_codec(x) -# define protected_mih_c_msg_codec(x) -# define public_mih_c_msg_codec(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/time.h> -#include <ctype.h> -#include <libgen.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -#define MIH_MESSAGE_DECODE_OK 0 -#define MIH_MESSAGE_DECODE_TOO_SHORT -1 -#define MIH_MESSAGE_DECODE_FAILURE -2 -#define MIH_MESSAGE_DECODE_BAD_PARAMETER -3 -//----------------------------------------------------------------------------- -#define MSG_MIH_HEADER_SIZE_IN_BYTES 8 -//----------------------------------------------------------------------------- -typedef u_int16_t MIH_C_Message_Id_t; - -typedef struct MIH_C_Message_Wrapper { - MIH_C_Message_Id_t message_id; - union { -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - MIH_C_Message_Link_Register_indication_t link_register_indication; -#endif - MIH_C_Message_Link_Detected_indication_t link_detected_indication; - MIH_C_Message_Link_Up_indication_t link_up_indication; - MIH_C_Message_Link_Down_indication_t link_down_indication; - MIH_C_Message_Link_Parameters_Report_indication_t link_parameters_report_indication; - MIH_C_Message_Link_Going_Down_indication_t link_going_down_indication; - MIH_C_Message_Link_Handover_Imminent_indication_t link_handover_imminent_indication; - MIH_C_Message_Link_Handover_Complete_indication_t link_handover_complete_indication; - MIH_C_Message_Link_PDU_Transmit_Status_indication_t link_pdu_transmit_status_indication; - MIH_C_Message_Link_Capability_Discover_request_t link_capability_discover_request; - MIH_C_Message_Link_Capability_Discover_confirm_t link_capability_discover_confirm; - MIH_C_Message_Link_Event_Subscribe_request_t link_event_subscribe_request; - MIH_C_Message_Link_Event_Subscribe_confirm_t link_event_subscribe_confirm; - MIH_C_Message_Link_Event_Unsubscribe_request_t link_event_unsubscribe_request; - MIH_C_Message_Link_Event_Unsubscribe_confirm_t link_event_unsubscribe_confirm; - MIH_C_Message_Link_Get_Parameters_request_t link_get_parameters_request; - MIH_C_Message_Link_Get_Parameters_confirm_t link_get_parameters_confirm; - MIH_C_Message_Link_Configure_Thresholds_request_t link_configure_thresholds_request; - MIH_C_Message_Link_Configure_Thresholds_confirm_t link_configure_thresholds_confirm; - MIH_C_Message_Link_Action_request_t link_action_request; - MIH_C_Message_Link_Action_confirm_t link_action_confirm; - } _union_message; -} MIH_C_Message_Wrapper_t; -//----------------------------------------------------------------------------- -private_mih_c_msg_codec(MIH_C_TRANSACTION_ID_T g_transaction_id_generator;) -//----------------------------------------------------------------------------- -public_mih_c_msg_codec( MIH_C_TRANSACTION_ID_T MIH_C_get_new_transaction_id(void);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Decode_Link_Capability_Discover_request( Bit_Buffer_t* bbP, MIH_C_Message_Link_Capability_Discover_request_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Link_Capability_Discover_request2String( MIH_C_Message_Link_Capability_Discover_request_t *messageP, char* bufP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Decode_Link_Event_Subscribe_request( Bit_Buffer_t* bbP, MIH_C_Message_Link_Event_Subscribe_request_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Link_Event_Subscribe_request2String( MIH_C_Message_Link_Event_Subscribe_request_t *messageP, char* bufP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Decode_Link_Event_Unsubscribe_request( Bit_Buffer_t* bbP, MIH_C_Message_Link_Event_Unsubscribe_request_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Link_Event_Unsubscribe_request2String( MIH_C_Message_Link_Event_Unsubscribe_request_t *messageP, char* bufP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Decode_Link_Get_Parameters_request( Bit_Buffer_t* bbP, MIH_C_Message_Link_Get_Parameters_request_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Link_Get_Parameters_request2String( MIH_C_Message_Link_Get_Parameters_request_t *messageP, char* bufP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Decode_Link_Configure_Thresholds_request( Bit_Buffer_t* bbP, MIH_C_Message_Link_Configure_Thresholds_request_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Link_Configure_Thresholds_request2String( MIH_C_Message_Link_Configure_Thresholds_request_t *messageP, char* bufP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Decode_Link_Action_request( Bit_Buffer_t* bbP, MIH_C_Message_Link_Action_request_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Link_Action_request2String( MIH_C_Message_Link_Action_request_t *messageP, char* bufP);) - -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Link_Register_indication( Bit_Buffer_t* bbP, MIH_C_Message_Link_Register_indication_t *messageP);) -#endif -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Link_Detected_indication( Bit_Buffer_t* bbP, MIH_C_Message_Link_Detected_indication_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Link_Up_indication( Bit_Buffer_t* bbP, MIH_C_Message_Link_Up_indication_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Link_Parameters_Report_indication( Bit_Buffer_t* bbP, MIH_C_Message_Link_Parameters_Report_indication_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Link_Going_Down_indication( Bit_Buffer_t* bbP, MIH_C_Message_Link_Going_Down_indication_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Link_Down_indication( Bit_Buffer_t* bbP, MIH_C_Message_Link_Down_indication_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Link_Action_confirm( Bit_Buffer_t* bbP, MIH_C_Message_Link_Action_confirm_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Capability_Discover_confirm( Bit_Buffer_t* bbP, MIH_C_Message_Link_Capability_Discover_confirm_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Event_Subscribe_confirm( Bit_Buffer_t* bbP, MIH_C_Message_Link_Event_Subscribe_confirm_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Event_Unsubscribe_confirm( Bit_Buffer_t* bbP, MIH_C_Message_Link_Event_Unsubscribe_confirm_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Configure_Thresholds_confirm( Bit_Buffer_t* bbP, MIH_C_Message_Link_Configure_Thresholds_confirm_t *messageP);) -public_mih_c_msg_codec( int MIH_C_Link_Message_Encode_Get_Parameters_confirm( Bit_Buffer_t* bbP, MIH_C_Message_Link_Get_Parameters_confirm_t *messageP);) -#endif diff --git a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_primitive_codec.h b/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_primitive_codec.h deleted file mode 100755 index 4b154a228c..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/INCLUDE/MIH_C_primitive_codec.h +++ /dev/null @@ -1,115 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file MIH_C_primitive_codec.h - * \brief This file defines the prototypes of the functions for coding and decoding of MIH Link messages. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MIH_C_PRIMITIVE_CODEC_H__ -# define __MIH_C_PRIMITIVE_CODEC_H__ -//----------------------------------------------------------------------------- -# ifdef mih_c_primitive_codec_C -# define private_mih_c_primitive_codec(x) x -# define protected_mih_c_primitive_codec(x) x -# define public_mih_c_primitive_codec(x) x -# else -# ifdef MIH_C_INTERFACE -# define private_mih_c_primitive_codec(x) -# define protected_mih_c_primitive_codec(x) extern x -# define public_mih_c_primitive_codec(x) extern x -# else -# define private_mih_c_primitive_codec(x) -# define protected_mih_c_primitive_codec(x) -# define public_mih_c_primitive_codec(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <netdb.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/time.h> -#include <ctype.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <getopt.h> -#include <libgen.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -#define MIH_PRIMITIVE_DECODE_OK 0 -#define MIH_PRIMITIVE_DECODE_TOO_SHORT -1 -#define MIH_PRIMITIVE_DECODE_FAILURE -2 -#define MIH_PRIMITIVE_DECODE_BAD_PARAMETER -3 -#define MIH_PRIMITIVE_ENCODE_OK 0 -#define MIH_PRIMITIVE_ENCODE_TOO_SHORT -1 -#define MIH_PRIMITIVE_ENCODE_FAILURE -2 -#define MIH_PRIMITIVE_ENCODE_BAD_PARAMETER -3 -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Decode_Link_Capability_Discover_request (Bit_Buffer_t* bbP, MIH_C_Link_Capability_Discover_request_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Link_Capability_Discover_request2String (MIH_C_Link_Capability_Discover_request_t *primitiveP, char* bufP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Decode_Link_Event_Subscribe_request (Bit_Buffer_t* bbP, MIH_C_Link_Event_Subscribe_request_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Link_Event_Subscribe_request2String (MIH_C_Link_Event_Subscribe_request_t *primitiveP, char* bufP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Decode_Link_Event_Unsubscribe_request (Bit_Buffer_t* bbP, MIH_C_Link_Event_Unsubscribe_request_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Link_Event_Unsubscribe_request2String (MIH_C_Link_Event_Unsubscribe_request_t *primitiveP, char* bufP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Decode_Link_Get_Parameters_request (Bit_Buffer_t* bbP, MIH_C_Link_Get_Parameters_request_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Link_Get_Parameters_request2String (MIH_C_Link_Get_Parameters_request_t *primitiveP, char* bufP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Decode_Link_Configure_Thresholds_request(Bit_Buffer_t* bbP, MIH_C_Link_Configure_Thresholds_request_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Link_Configure_Thresholds_request2String(MIH_C_Link_Configure_Thresholds_request_t *primitiveP, char* bufP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Decode_Link_Action_request (Bit_Buffer_t* bbP, MIH_C_Link_Action_request_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Link_Action_request2String (MIH_C_Link_Action_request_t *primitiveP, char* bufP);) - -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Register_indication (Bit_Buffer_t* bbP, MIH_C_Link_Register_indication_t *primitiveP);) -#endif -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Detected_indication (Bit_Buffer_t* bbP, MIH_C_Link_Detected_indication_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Up_indication (Bit_Buffer_t* bbP, MIH_C_Link_Up_indication_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Parameters_Report_indication(Bit_Buffer_t* bbP, MIH_C_Link_Parameters_Report_indication_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Going_Down_indication (Bit_Buffer_t* bbP, MIH_C_Link_Going_Down_indication_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Down_indication (Bit_Buffer_t* bbP, MIH_C_Link_Down_indication_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Link_Register_indication2String (MIH_C_Link_Register_indication_t *primitiveP, char* bufP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Capability_Discover_confirm (Bit_Buffer_t* bbP, MIH_C_Link_Capability_Discover_confirm_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Link_Capability_Discover_confirm2String (MIH_C_Link_Capability_Discover_confirm_t *primitiveP, char* bufP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Event_Subscribe_confirm (Bit_Buffer_t* bbP, MIH_C_Link_Event_Subscribe_confirm_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Event_Unsubscribe_confirm (Bit_Buffer_t* bbP, MIH_C_Link_Event_Unsubscribe_confirm_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Configure_Thresholds_confirm(Bit_Buffer_t* bbP, MIH_C_Link_Configure_Thresholds_confirm_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Get_Parameters_confirm (Bit_Buffer_t* bbP, MIH_C_Link_Get_Parameters_confirm_t *primitiveP);) -protected_mih_c_primitive_codec(int MIH_C_Link_Primitive_Encode_Link_Action_confirm (Bit_Buffer_t* bbP, MIH_C_Link_Action_confirm_t *primitiveP);) -#endif diff --git a/openair3/RAL-LTE/INTERFACE-802.21/Makefile b/openair3/RAL-LTE/INTERFACE-802.21/Makefile deleted file mode 100755 index fbb6428fb0..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# lines starting with the pound sign are comments. -# -# These things are options that you might need -# to tweak. - - -# You can modify the below as well, but probably -# won't need to. -CODE_DIR=C -INCLUDE_DIR=INCLUDE -LIB_DIR=LIB - -CC = gcc - -# include directories -INCLUDES = -I$(INCLUDE_DIR) - -# C compiler flags (-g -O2 -Wall) -CFLAGS = -g -Wall -DMIH_C_MEDIEVAL_EXTENSIONS - - - - -SRC = $(CODE_DIR)/MIH_C_header_codec.c -SRC += $(CODE_DIR)/MIH_C_msg_codec.c -SRC += $(CODE_DIR)/MIH_C_primitive_codec.c -SRC += $(CODE_DIR)/MIH_C_F1_basic_data_types_codec.c -SRC += $(CODE_DIR)/MIH_C_F2_general_data_types_codec.c -SRC += $(CODE_DIR)/MIH_C_F3_data_types_for_address_codec.c -SRC += $(CODE_DIR)/MIH_C_F4_data_types_for_links_codec.c -SRC += $(CODE_DIR)/MIH_C_F9_data_types_for_qos_codec.c -SRC += $(CODE_DIR)/MIH_C_F13_data_types_for_information_elements_codec.c -SRC += $(CODE_DIR)/MIH_C_L2_type_values_for_tlv_encoding.c -SRC += $(CODE_DIR)/MIH_C_Medieval_extensions.c -SRC += $(CODE_DIR)/MIH_C_log.c -SRC += $(CODE_DIR)/MIH_C_bit_buffer.c -SRC += $(CODE_DIR)/MIH_C.c - -OBJ = $(SRC:.c=.o) - -LIBS = -L/usr/local/lib -lrt - -OUT = $(LIB_DIR)/libmih_c-802.21.a - - - -LDFLAGS = -g - -.SUFFIXES: .c - -default: $(OUT) - -.c.o: - $(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@ - -$(OUT): $(OBJ) - ar rcs $(OUT) $(OBJ) - - -clean: - -find . -name "*.o" -delete - -find . -name "*.*~" -delete - -find . -name "*~" -delete - -rm -Rf DOXYGEN/html - -rm -f $(OUT) - - - diff --git a/openair3/RAL-LTE/INTERFACE-802.21/readme.txt b/openair3/RAL-LTE/INTERFACE-802.21/readme.txt deleted file mode 100755 index aa8c754e58..0000000000 --- a/openair3/RAL-LTE/INTERFACE-802.21/readme.txt +++ /dev/null @@ -1,14 +0,0 @@ -Doc updated on 11 June 2012 - -README file for INTERFACE-802.21 Interface - - ****************** - Release dates - - Beta 0 : 06.11.2012 - ****************** - - The mih_c-802.21.a library is compiled in the INTERFACE-802.21 directory . - - This library can be linked with any C module dealing with 802.21 link interface. - diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb.h deleted file mode 100755 index 6ac43bd37e..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb.h +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef __LTE_RAL_ENB_H__ -#define __LTE_RAL_ENB_H__ - -#include "MIH_C.h" - -#include "openair_types.h" -#include "platform_constants.h" -#include "platform_types.h" - -#include "lteRALenb_constants.h" -#include "lteRALenb_variables.h" -#include "lteRALenb_action.h" -#include "lteRALenb_main.h" -#include "lteRALenb_mih_msg.h" -#include "lteRALenb_rrc_msg.h" -#include "lteRALenb_parameters.h" -#include "lteRALenb_process.h" -#include "lteRALenb_subscribe.h" -#include "lteRALenb_thresholds.h" -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_action.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_action.h deleted file mode 100755 index 3a654bd2b3..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_action.h +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_action.h - * \brief - * \author GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_ENB_ACTION_H__ -#define __LTE_RAL_ENB_ACTION_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_ENB_ACTION_C -# define private_lteralenb_action(x) x -# define protected_lteralenb_action(x) x -# define public_lteralenb_action(x) x -# else -# ifdef LTE_RAL_ENB -# define private_lteralenb_action(x) -# define protected_lteralenb_action(x) extern x -# define public_lteralenb_action(x) extern x -# else -# define private_lteralenb_action(x) -# define protected_lteralenb_action(x) -# define public_lteralenb_action(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALenb.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - -/* - * --------------------------------------------------------------------------- - * Flow identifier management: - * Radio Bearer data flows are identified by a source address, a destination - * address and a port number for a particular IP transport protocol (UDP, - * TCP). A private data structure is used to map upper-layer flow identifiers - * to lower-layer RB channel identifiers. It is handled by private functions. - * --------------------------------------------------------------------------- - */ -/* Structure of the destination data flow */ -typedef struct Data_flow { - unsigned char addr[16]; // IP address - unsigned int l2id[2]; // L2 identifier - unsigned int port; // IP port identifier - int proto; // IP protocol - int cnxid; // Data flow identifier -} data_flow_t; - -#define ACTION_MAX_FLOW ((RAL_MAX_MT)*(RAL_MAX_RB)) - -typedef struct eRAL_action_DataFlowList { - int n_flows; - data_flow_t flow [ACTION_MAX_FLOW]; - int flow_id [ACTION_MAX_FLOW]; //added TEMP MW 23/05/13 -} eRAL_action_DataFlowList_t; - -private_lteralenb_action(eRAL_action_DataFlowList_t g_flows = {};) - -#endif // MIH_C_MEDIEVAL_EXTENSIONS -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -protected_lteralenb_action(void eRAL_action_request (ral_enb_instance_t instanceP, MIH_C_Message_Link_Action_request_t* msgP);) -protected_lteralenb_action(int eRAL_action_save_flow_id (ral_enb_instance_t instanceP, MIH_C_FLOW_ID_T* flowId, int cnxid);) -private_lteralenb_action( int eRAL_action_set_channel_id (ral_enb_instance_t instanceP, MIH_C_FLOW_ID_T* flowId, int cnxid);) -private_lteralenb_action( int eRAL_action_get_channel_id (ral_enb_instance_t instanceP, MIH_C_FLOW_ID_T* flowId, int* cnxid);) -private_lteralenb_action( int eRAL_action_del_channel_id (ral_enb_instance_t instanceP, int fix);) -private_lteralenb_action( int eRAL_action_is_in_progress (ral_enb_instance_t instanceP, MIH_C_STATUS_T* status, MIH_C_LINK_AC_RESULT_T* ac_status, MIH_C_LINK_AC_TYPE_T action);) -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -private_lteralenb_action( MIH_C_LINK_AC_RESULT_T eRAL_action_link_flow_attr(ral_enb_instance_t instanceP);) -private_lteralenb_action( MIH_C_LINK_AC_RESULT_T eRAL_action_link_activate_resources(ral_enb_instance_t instanceP);) -private_lteralenb_action( MIH_C_LINK_AC_RESULT_T eRAL_action_link_deactivate_resources(ral_enb_instance_t instanceP);) -#endif // MIH_C_MEDIEVAL_EXTENSIONS - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_constants.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_constants.h deleted file mode 100755 index 6d791127ea..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_constants.h +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef __LTE_RAL_ENB_CONSTANTS_H__ -#define __LTE_RAL_ENB_CONSTANTS_H__ - -#include <sys/types.h> - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -//----------------------------------------------------------------------------- -#define ENB_DEFAULT_LOCAL_PORT_RAL "1235" -#define ENB_DEFAULT_REMOTE_PORT_MIHF "1025" -#define ENB_DEFAULT_IP_ADDRESS_MIHF "127.0.0.1" -#define ENB_DEFAULT_IP_ADDRESS_RAL "127.0.0.1" -#define ENB_DEFAULT_LINK_ID_RAL "enb_lte_link" -#define ENB_DEFAULT_LINK_ADDRESS_RAL "060080149150" -#define ENB_DEFAULT_MIHF_ID "mihf_enb" -#define ENB_DEFAULT_3GPP_ADDRESS "0000000000000000" - - -//----------------------------------------------------------------------------- -// Constants for scenario -#define PREDEFINED_MIH_NETWORK_ID "eurecom" -#define PREDEFINED_MIH_NETAUX_ID "netaux" - -#define PREDEFINED_CHANNEL_ID 2 -#define PREDEFINED_CLASSES_SERVICE_SUPPORTED 2 -#define PREDEFINED_QUEUES_SUPPORTED 2 - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_main.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_main.h deleted file mode 100755 index 93a99b8fa7..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_main.h +++ /dev/null @@ -1,218 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_main.h - * \brief - * \author GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_ENB_MAIN_H__ -#define __LTE_RAL_ENB_MAIN_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_ENB_MAIN_C -# define private_lteralenb_main(x) x -# define protected_lteralenb_main(x) x -# define public_lteralenb_main(x) x -# else -# ifdef LTE_RAL_ENB -# define private_lteralenb_main(x) -# define protected_lteralenb_main(x) extern x -# define public_lteralenb_main(x) extern x -# else -# define private_lteralenb_main(x) -# define protected_lteralenb_main(x) -# define public_lteralenb_main(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALenb.h" -#include "commonDef.h" -#include "hashtable.h" -//#include "collection/hashtable/hashtable.h" - -public_lteralenb_main(char* g_conf_enb_ral_listening_port;) -public_lteralenb_main(char* g_conf_enb_ral_ip_address;) -public_lteralenb_main(char* g_conf_enb_ral_link_id;) -public_lteralenb_main(char* g_conf_enb_ral_link_address;) -public_lteralenb_main(char* g_conf_enb_mihf_remote_port;) -public_lteralenb_main(char* g_conf_enb_mihf_ip_address;) -public_lteralenb_main(char* g_conf_enb_mihf_id;) - -/* - * Radio Bearer data - */ -typedef struct ral_lte_channel { - uint32_t cnx_id; - uint8_t multicast; - // MIHF parameters ix=0 UPLINK, ix=1 DOWNLINK - uint16_t flowId[2]; - uint16_t classId[2]; - float resBitrate[2]; - float meanBitrate[2]; - float bktDepth[2]; - float pkBitrate[2]; - float MTU[2]; - - // #if ! defined(ENABLE_USE_MME) - //IP driver parameters - uint16_t rbId; - uint16_t RadioQoSclass; - uint16_t dscpUL; - uint16_t dscpDL; - uint16_t nas_state; - uint16_t status; - // #endif -} ral_lte_channel_t; - -/* - * Mobile Terminal data - */ -typedef struct ral_lte_mt_s { - /* The identifier of the link that is associated with a PoA */ - MIH_C_LINK_TUPLE_ID_T ltid; - uint8_t ipv6_addr[16]; - uint32_t ipv6_l2id[2]; - uint32_t ue_id; - struct ral_lte_channel radio_channel[RAL_MAX_RB]; - int num_rbs; - int num_class; - int nas_state; - int mt_state; -} ral_lte_mt_t; - - -/* - * Multicast data // TEMP MW A supprimer!!!! - */ -typedef struct ral_lte_mcast_s { - /* The identifier of the multicast link that is associated with a PoA */ - MIH_C_LINK_TUPLE_ID_T ltid; - struct ral_lte_channel radio_channel; - uint8_t mc_group_addr[16]; -} ral_lte_mcast_t; - -/* - * RAL LTE internal data - */ - -typedef struct lte_ral_enb_object { - //------------------------ - // CONFIG PARAMETERS - //------------------------ - char* ral_listening_port; - char* ral_ip_address; - char* ral_link_address; - char* mihf_remote_port; - char* mihf_ip_address; - char* link_id; - char* mihf_id; - MIH_C_LINK_MIHCAP_FLAG_T link_mihcap_flag; // hardcoded parameters - MIH_C_NET_CAPS_T net_caps;// hardcoded parameters - - // provided by RRC with RRC_RAL_SYSTEM_CONFIGURATION_IND message - plmn_t plmn_id; - unsigned int cell_id:28; - - - int num_connected_mts; - - uint8_t pending_req_flag; - uint8_t pending_req_mt_ix; - uint8_t pending_req_ch_ix; - uint8_t pending_req_multicast; - // uint16_t pending_req_transaction_id; - // uint8_t pending_req_status; - MIH_C_FLOW_ID_T pending_req_fid; - - ral_lte_mt_t pending_mt; - int pending_mt_timer; - int pending_mt_flag; - - ral_lte_mt_t mt[RAL_MAX_MT]; - ral_lte_mcast_t mcast; - - // measurements for MEDIEVAL project - //MIH_C_TIMER_INTERVAL_T measurement_timer_interval; // This timer value (ms) is used to set the interval between - // periodic reports. Valid Range: 0..65535 - //long measurement_timer_id; - - //uint16_t num_UEs; - //uint32_t rlcBufferOccupancy[RAL_MAX_MT]; - //uint32_t scheduledPRB[RAL_MAX_MT]; - //uint32_t totalDataVolume[RAL_MAX_MT]; - //uint32_t totalNumPRBs; - - - //int congestion_flag; - //int congestion_threshold; - //int measures_triggered_flag; - //int requested_period; - - // MIH-INTERFACE data - int mih_sock_desc; - MIH_C_LINK_AC_TYPE_LIST_T mih_supported_link_action_list; - MIH_C_LINK_EVENT_LIST_T mih_supported_link_event_list; - MIH_C_LINK_CMD_LIST_T mih_supported_link_command_list; - MIH_C_LINK_EVENT_LIST_T mih_subscribe_req_event_list; - - //LIST(MIH_C_LINK_CFG_PARAM, mih_link_cfg_param_thresholds); - // to tell what are the configured thresholds in mih_link_cfg_param_thresholds_list - //MIH_C_BOOLEAN_T active_mih_link_cfg_param_threshold[MIH_C_LINK_CFG_PARAM_LIST_LENGTH]; - - - MIH_C_LINK_AC_TYPE_T pending_req_action; - MIH_C_STATUS_T pending_req_status; - MIH_C_LINK_AC_RESULT_T pending_req_ac_result; - MIH_C_TRANSACTION_ID_T pending_req_transaction_id; - - - hash_table_t *ue_htbl; - - MIH_C_TRANSACTION_ID_T transaction_id; - - char buffer[800]; -} lte_ral_enb_object_t; - - - -/* RAL LTE internal data */ -protected_lteralenb_main(lte_ral_enb_object_t g_enb_ral_obj[MAX_MODULES];) -private_lteralenb_main(hash_table_t *g_enb_ral_fd2instance;) - -private_lteralenb_main(void eRAL_get_IPv6_addr (const char* if_name);) -public_lteralenb_main( void eRAL_init_default_values (void);) -private_lteralenb_main(int eRAL_initialize (void);) -private_lteralenb_main(void eRAL_process_file_descriptors(struct epoll_event *events, int nb_events);) -public_lteralenb_main( void* eRAL_task (void *args_p);) - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_mih_msg.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_mih_msg.h deleted file mode 100755 index a6b16249d3..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_mih_msg.h +++ /dev/null @@ -1,202 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_mih_msg.h - * \brief - * \author GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_ENB_MIH_MSG_H__ -#define __LTE_RAL_ENB_MIH_MSG_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_ENB_MIH_MSG_C -# define private_lteralenb_mih_msg(x) x -# define protected_lteralenb_mih_msg(x) x -# define public_lteralenb_mih_msg(x) x -# else -# ifdef LTE_RAL_ENB -# define private_lteralenb_mih_msg(x) -# define protected_lteralenb_mih_msg(x) extern x -# define public_lteralenb_mih_msg(x) extern x -# else -# define private_lteralenb_mih_msg(x) -# define protected_lteralenb_mih_msg(x) -# define public_lteralenb_mih_msg(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALenb.h" - -#include "MIH_C_Types.h" -#include "MIH_C_header_codec.h" -#include "MIH_C_Link_Primitives.h" - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ -protected_lteralenb_mih_msg(void eRAL_MIH_C_3GPP_ADDR_load_3gpp_str_address(ral_enb_instance_t instanceP, MIH_C_3GPP_ADDR_T* _3gpp_addr_pP, u_int8_t* str_pP)); - -protected_lteralenb_mih_msg(int eRAL_mihf_connect(ral_enb_instance_t instanceP);) - -protected_lteralenb_mih_msg(int eRAL_mih_link_process_message(ral_enb_instance_t instanceP);) -private_lteralenb_mih_msg(void eRAL_print_buffer(const u_int8_t * bufferP, int lenP);) -/* - * -------------------------------------------------------------------------- - * MIH service management messages - * -------------------------------------------------------------------------- - */ - -/* MIH_C_MESSAGE_LINK_REGISTER_INDICATION_ID */ -protected_lteralenb_mih_msg(void eRAL_send_link_register_indication(\ - ral_enb_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP);) - -/* MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_CONFIRM_ID */ -private_lteralenb_mih_msg(void eRAL_send_capability_discover_confirm(\ - ral_enb_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *tidP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_EVENT_LIST_T *link_evt_listP,\ - MIH_C_LINK_CMD_LIST_T *link_cmd_listP);) - -/* MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_CONFIRM_ID */ -protected_lteralenb_mih_msg(void eRAL_send_event_subscribe_confirm(\ - ral_enb_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_EVENT_LIST_T *link_event_listP);) - -/* MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_CONFIRM_ID */ -protected_lteralenb_mih_msg(void eRAL_send_event_unsubscribe_confirm(\ - ral_enb_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_EVENT_LIST_T *link_event_listP);) - -/* - * -------------------------------------------------------------------------- - * MIH event messages - * -------------------------------------------------------------------------- - */ - -/* MIH_C_MESSAGE_LINK_DETECTED_INDICATION_ID */ -protected_lteralenb_mih_msg(void eRAL_send_link_detected_indication(\ - ral_enb_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_LINK_DET_INFO_T *link_detected_infoP);) - -/* MIH_C_MESSAGE_LINK_UP_INDICATION_ID */ -protected_lteralenb_mih_msg(void eRAL_send_link_up_indication(\ - ral_enb_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_LINK_TUPLE_ID_T *link_identifierP,\ - MIH_C_LINK_ADDR_T *old_access_routerP,\ - MIH_C_LINK_ADDR_T *new_access_routerP,\ - MIH_C_IP_RENEWAL_FLAG_T *ip_renewal_flagP,\ - MIH_C_IP_MOB_MGMT_T *mobility_mngtP);) - -/* MIH_C_MESSAGE_LINK_DOWN_INDICATION_ID */ -private_lteralenb_mih_msg(void eRAL_send_link_down_indication(\ - ral_enb_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_LINK_TUPLE_ID_T *link_identifierP,\ - MIH_C_LINK_ADDR_T *old_access_routerP,\ - MIH_C_LINK_DN_REASON_T *reason_codeP);) - -/* MIH_C_MESSAGE_LINK_PARAMETERS_REPORT_INDICATION_ID */ -protected_lteralenb_mih_msg(void eRAL_send_link_parameters_report_indication(\ - ral_enb_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_LINK_TUPLE_ID_T *link_identifierP,\ - MIH_C_LINK_PARAM_RPT_LIST_T *link_parameters_report_listP);) - -/* MIH_C_MESSAGE_LINK_GOING_DOWN_INDICATION_ID */ -private_lteralenb_mih_msg(void eRAL_send_link_going_down_indication(\ - ral_enb_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_LINK_TUPLE_ID_T *link_identifierP,\ - MIH_C_UNSIGNED_INT2_T *time_intervalP,\ - MIH_C_LINK_GD_REASON_T *link_going_down_reasonP);) - -/* MIH_C_MESSAGE_LINK_HANDOVER_IMMINENT_INDICATION_ID */ - -/* MIH_C_MESSAGE_LINK_HANDOVER_COMPLETE_INDICATION_ID */ - -/* MIH_C_MESSAGE_LINK_PDU_TRANSMIT_STATUS_INDICATION_ID */ - -/* - * -------------------------------------------------------------------------- - * MIH command messages - * -------------------------------------------------------------------------- - */ - -/* MIH_C_MESSAGE_LINK_GET_PARAMETERS_CONFIRM_ID */ -protected_lteralenb_mih_msg(void eRAL_send_get_parameters_confirm(\ - ral_enb_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_PARAM_LIST_T *link_parameters_status_listP,\ - MIH_C_LINK_STATES_RSP_LIST_T *link_states_response_listP,\ - MIH_C_LINK_DESC_RSP_LIST_T *link_descriptors_response_listP);) - -/* MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_CONFIRM_ID */ -protected_lteralenb_mih_msg(void eRAL_send_configure_thresholds_confirm(\ - ral_enb_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_CFG_STATUS_LIST_T *link_configure_status_listP);) - -/* MIH_C_MESSAGE_LINK_ACTION_CONFIRM_ID */ -protected_lteralenb_mih_msg(void eRAL_send_link_action_confirm(\ - ral_enb_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_SCAN_RSP_LIST_T *scan_response_setP,\ - MIH_C_LINK_AC_RESULT_T *link_action_resultP);) - -/* - * -------------------------------------------------------------------------- - * MIH information messages - * -------------------------------------------------------------------------- - */ -protected_lteralenb_mih_msg(int eRAL_mihf_connect (ral_enb_instance_t instanceP);) -private_lteralenb_mih_msg( int eRAL_send_to_mih (ral_enb_instance_t instanceP, const u_int8_t *bufferP, int lenP);) -private_lteralenb_mih_msg( int eRAL_mih_link_msg_decode(ral_enb_instance_t instanceP, Bit_Buffer_t* bbP, MIH_C_Message_Wrapper_t *message_wrapperP);) -/****************************************************************************/ - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_parameters.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_parameters.h deleted file mode 100755 index 10d44c47c6..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_parameters.h +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_parameters.h - * \brief - * \author GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_ENB_PARAMETERS_H__ -#define __LTE_RAL_ENB_PARAMETERS_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_ENB_PARAMETERS_C -# define private_lteralenb_parameters(x) x -# define protected_lteralenb_parameters(x) x -# define public_lteralenb_parameters(x) x -# else -# ifdef LTE_RAL_ENB -# define private_lteralenb_parameters(x) -# define protected_lteralenb_parameters(x) extern x -# define public_lteralenb_parameters(x) extern x -# else -# define private_lteralenb_parameters(x) -# define protected_lteralenb_parameters(x) -# define public_lteralenb_parameters(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALenb.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -void eRAL_get_parameters_request(ral_enb_instance_t instanceP, MIH_C_Message_Link_Get_Parameters_request_t* messageP); - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_process.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_process.h deleted file mode 100755 index 9f5024de0b..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_process.h +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_process.h - * \brief - * \author GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_ENB_PROCESS_H__ -#define __LTE_RAL_ENB_PROCESS_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_ENB_PROCESS_C -# define private_lteralenb_process(x) x -# define protected_lteralenb_process(x) x -# define public_lteralenb_process(x) x -# else -# ifdef LTE_RAL_ENB -# define private_lteralenb_process(x) -# define protected_lteralenb_process(x) extern x -# define public_lteralenb_process(x) extern x -# else -# define private_lteralenb_process(x) -# define protected_lteralenb_process(x) -# define public_lteralenb_process(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALenb.h" - -protected_lteralenb_process(int eRAL_process_find_channel (ral_enb_instance_t instanceP, unsigned int cnxid, int* mt_ix, int* ch_ix);) -protected_lteralenb_process(int eRAL_process_find_new_channel (ral_enb_instance_t instanceP, int mt_ix);) -private_lteralenb_process( void eRAL_process_clean_channel (struct ral_lte_channel* channel);) -protected_lteralenb_process(char* eRAL_process_mt_addr_to_string (const unsigned char* ip_addr);) -protected_lteralenb_process(void eRAL_process_mt_addr_to_l2id (const unsigned char* mt_addr, unsigned int* l2id);) -private_lteralenb_process( int eRAL_process_cmp_mt_addr (const char* mt_addr, const char* l2id);) -protected_lteralenb_process(int eRAL_process_find_mt_by_addr (ral_enb_instance_t instanceP, const char* mt_addr);) -private_lteralenb_process( void eRAL_process_verify_pending_mt_status(ral_enb_instance_t instanceP);) -protected_lteralenb_process(int eRAL_process_map_qos (ral_enb_instance_t instanceP, int mt_ix, int ch_ix);) -private_lteralenb_process( void eRAL_process_waiting_RB (ral_enb_instance_t instanceP, int mt_ix);) -private_lteralenb_process( void eRAL_process_clean_pending_mt (ral_enb_instance_t instanceP);) -protected_lteralenb_process(void RAL_printInitStatus (ral_enb_instance_t instanceP);) -private_lteralenb_process( void RAL_NAS_measures_polling (ral_enb_instance_t instanceP);) -private_lteralenb_process( void RAL_NAS_report_congestion (ral_enb_instance_t instanceP, int ix);) -private_lteralenb_process( void RAL_NAS_measures_analyze (ral_enb_instance_t instanceP);) -#endif - diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_proto.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_proto.h deleted file mode 100755 index cdc270b21c..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_proto.h +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_proto.h - * \brief This file defines the prototypes of the common functions - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#ifndef __LTE_RAL_ENB_PROTO_H__ -#define __LTE_RAL_ENB_PROTO_H__ - -# error "Remove inclusion" -//#include "lteRALenb_variables.h" -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ -/* - * Functions defined in eRALlte_NAS.c - */ - -//void eRALlte_NAS_get_MTs_list(void); -//int eRALlte_NAS_update_MTs_list(void); - -//int eRALlte_NAS_process_message(void); -//int eRALlte_NAS_send_rb_establish_request(int mt_ix, int ch_ix); -//int eRALlte_NAS_send_rb_release_request(int mt_ix, int ch_ix); -//int eRALlte_NAS_send_measure_request(void); - -//#ifdef RAL_REALTIME -//int RAL_process_NAS_message(int ioctl_obj, int ioctl_cmd, int mt_ix, int ch_ix); -//#endif - -/* - * Functions defined in eRALlte_process.c - */ -//int eRALlte_process_find_channel(unsigned int cnxid, int* mt_ix, int* ch_ix); -//int eRALlte_process_find_new_channel(int mt_ix); -//void eRALlte_process_clean_channel(struct ral_lte_channel* pchannel); -//void eRALlte_process_verify_pending_mt_status(void); -//char* eRALlte_process_mt_addr_to_string(const unsigned char* mt_addr); -//void eRALlte_process_mt_addr_to_l2id(const unsigned char* mt_addr, unsigned int* l2id); -//int eRALlte_process_cmp_mt_addr(const char* mt_addr, const char* l2id); -//int eRALlte_process_find_mt_by_addr(const char* mt_addr); -//int eRALlte_process_map_qos(int mt_ix, int ch_ix); -// MW Added -//void RAL_printInitStatus(void); -//void RAL_NAS_measures_polling(void); -//void RAL_NAS_measures_analyze(void); -//void RAL_NAS_report_congestion(int ix); - -//void* ral_enb_task(void *args_p); - -#endif - diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_rrc_msg.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_rrc_msg.h deleted file mode 100755 index 87f5bda0a1..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_rrc_msg.h +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_rrc_msg.h - * \brief - * \author GAUTHIER Lionel - * \date 2013 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_ENB_RRC_MSG_H__ -#define __LTE_RAL_ENB_RRC_MSG_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_ENB_RRC_MSG_C -# define private_lteralenb_rrc_msg(x) x -# define protected_lteralenb_rrc_msg(x) x -# define public_lteralenb_rrc_msg(x) x -# else -# ifdef LTE_RAL_ENB -# define private_lteralenb_rrc_msg(x) -# define protected_lteralenb_rrc_msg(x) extern x -# define public_lteralenb_rrc_msg(x) extern x -# else -# define private_lteralenb_rrc_msg(x) -# define protected_lteralenb_rrc_msg(x) -# define public_lteralenb_rrc_msg(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALenb.h" -#include "intertask_interface.h" - -protected_lteralenb_rrc_msg(void eRAL_rx_rrc_ral_system_configuration_indication (instance_t instance, MessageDef *msg_p);) -protected_lteralenb_rrc_msg(void eRAL_rx_rrc_ral_connection_establishment_indication (instance_t instance, MessageDef *msg_p);) -protected_lteralenb_rrc_msg(void eRAL_rx_rrc_ral_connection_reestablishment_indication (instance_t instance, MessageDef *msg_p);) -protected_lteralenb_rrc_msg(void eRAL_rx_rrc_ral_connection_reconfiguration_indication (instance_t instance, MessageDef *msg_p);) -protected_lteralenb_rrc_msg(void eRAL_rx_rrc_ral_measurement_report_indication (instance_t instance, MessageDef *msg_p);) -protected_lteralenb_rrc_msg(void eRAL_rx_rrc_ral_connection_release_indication (instance_t instance, MessageDef *msg_p);) - - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_subscribe.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_subscribe.h deleted file mode 100755 index 8dbf663cbd..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_subscribe.h +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_subscribe.h - * \brief - * \author GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_ENB_SUBSCRIBE_H__ -#define __LTE_RAL_ENB_SUBSCRIBE_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_ENB_PROCESS_C -# define private_lteralenb_subscribe(x) x -# define protected_lteralenb_subscribe(x) x -# define public_lteralenb_subscribe(x) x -# else -# ifdef LTE_RAL_ENB -# define private_lteralenb_subscribe(x) -# define protected_lteralenb_subscribe(x) extern x -# define public_lteralenb_subscribe(x) extern x -# else -# define private_lteralenb_subscribe(x) -# define protected_lteralenb_subscribe(x) -# define public_lteralenb_subscribe(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALenb.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -protected_lteralenb_subscribe(void eRAL_subscribe_request(ral_enb_instance_t instanceP, MIH_C_Message_Link_Event_Subscribe_request_t* msgP);) - -protected_lteralenb_subscribe(void eRAL_unsubscribe_request(ral_enb_instance_t instanceP, MIH_C_Message_Link_Event_Unsubscribe_request_t* msgP);) - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_thresholds.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_thresholds.h deleted file mode 100755 index 7d5e8b5471..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_thresholds.h +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_thresholds.h - * \brief - * \author GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_ENB_THRESHOLDS_H__ -#define __LTE_RAL_ENB_THRESHOLDS_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_ENB_PROCESS_C -# define private_lteralenb_thresholds(x) x -# define protected_lteralenb_thresholds(x) x -# define public_lteralenb_thresholds(x) x -# else -# ifdef LTE_RAL_ENB -# define private_lteralenb_thresholds(x) -# define protected_lteralenb_thresholds(x) extern x -# define public_lteralenb_thresholds(x) extern x -# else -# define private_lteralenb_thresholds(x) -# define protected_lteralenb_thresholds(x) -# define public_lteralenb_thresholds(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALenb.h" -#include "intertask_interface.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -//LIST(MIH_C_LINK_CFG_PARAM, g_link_cfg_param_thresholds); - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -protected_lteralenb_thresholds(void eRAL_configure_thresholds_request(ral_enb_instance_t instanceP, MIH_C_Message_Link_Configure_Thresholds_request_t* messageP);) -protected_lteralenb_thresholds(void eRAL_rx_rrc_ral_configure_threshold_conf(instance_t instance, MessageDef *msg_p);) - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_variables.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_variables.h deleted file mode 100755 index 53f9af00eb..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/lteRALenb_variables.h +++ /dev/null @@ -1,166 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef __LTE_RAL_ENB_VARIABLES_H__ -#define __LTE_RAL_ENB_VARIABLES_H__ - -// Define working mode : Dummy or Realtime -//#define RAL_DUMMY -#define RAL_REALTIME - -//#define ENABLE_MEDIEVAL_DEMO3 -//#define MUSER_CONTROL // in demo3, for triggering the congestion report manually - -//flag to reduce the logs -#define DEBUG_RAL_DETAILS - - - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -#ifdef RAL_REALTIME -/*Arguments ioctl command - */ -//arg[0] -//LG#define IO_OBJ_STATS 0 -//LG#define IO_OBJ_CNX 1 -//LG#define IO_OBJ_RB 2 -//LG#define IO_OBJ_MEAS 3 -//LG#define IO_OBJ_MC 4 // multicast - -//arg[1] -//LG#define IO_CMD_ADD 0 -//LG#define IO_CMD_DEL 1 -//LG#define IO_CMD_LIST 2 - -#define NAS_CONNECTED 1 //same as NAS interface -#define NAS_DISCONNECTED 0 -#endif // RAL_REALTIME - -/* Radio Bearer attachment status; must be the same as NAS interface */ -#define RB_CONNECTED NAS_CONNECTED -#define RB_DISCONNECTED NAS_DISCONNECTED - -#define RAL_TRUE 1 -#define RAL_FALSE 0 - - -/*Access Router configuration - */ -#ifdef RAL_REALTIME -//#define NAS_RG_NETL_MAX_RABS 27 //spec value -#define NAS_RG_NETL_MAX_RABS 5 //test value -#define NAS_RG_NETL_MAX_MEASURE_NB 5 -#define NAS_RG_NETL_MAX_MTs 3 -#endif - -/* Maximum number of supported Radio Bearers */ -#define RAL_MAX_RB NAS_RG_NETL_MAX_RABS -/* Maximum number of supported Mobile Terminals */ -#define RAL_MAX_MT NAS_RG_NETL_MAX_MTs -/* Maximum number of Radio Bearers per User Equipment */ -#define RAL_MAX_RB_PER_UE 32 -/* Default Radio Bearer identifier */ -#define RAL_DEFAULT_MC_RAB_ID 5 -#define RAL_DEFAULT_RAB_ID 6 // RBID 5 => MBMS, 6 => DEFAULTRAB, 7+ => others -/* Default Radio Bearer QoS value */ -#define RAL_DEFAULT_RAB_QoS 2 // RRC_QOS_CONV_64_64 -/* Default current cell identifier */ -#define RAL_DEFAULT_CELL_ID 5 -// Constants for Measures -#define RAL_DEFAULT_MEAS_POLLING_INTERVAL 51 -#define RAL_DEFAULT_CONGESTION_THRESHOLD 80 - -/* Default bit rates */ -#define RAL_BITRATE_32k 32000 -#define RAL_BITRATE_64k 64000 -#define RAL_BITRATE_128k 128000 -#define RAL_BITRATE_256k 256000 -#define RAL_BITRATE_320k 320000 -#define RAL_BITRATE_384k 384000 -#define RAL_BITRATE_440k 440000 - -/* Public Land Mobile Network */ -#define DEFAULT_PLMN_SIZE 3 -#ifdef DEFINE_GLOBAL_CONSTANTS -const u_int8_t DefaultPLMN[DEFAULT_PLMN_SIZE] = {0x20, 0x80, 0x20}; -#else -extern const u_int8_t DefaultPLMN[DEFAULT_PLMN_SIZE]; -#endif - -/*Destination addresses - */ -enum { - ADDR_MT1 = 0, - ADDR_MT2, - ADDR_MBMS, - ADDR_MT3, - ADDR_MAX -}; - -#ifdef DEFINE_GLOBAL_CONSTANTS // Modified MW 23/05/13 -const char DestIpv6Addr[ADDR_MAX][16] = { // DUMMY - // MT1 - 2001:660:382:14:335:600:8014:9150 - {0x20,0x01,0x06,0x60,0x03,0x82,0x00,0x14,0x03,0x35,0x06,0x00,0x80,0x14,0x91,0x50}, - // MT2 - 2001:660:382:14:335:600:8014:9151 - {0x20,0x01,0x06,0x60,0x03,0x82,0x00,0x14,0x03,0x35,0x06,0x00,0x80,0x14,0x91,0x51}, - // Multicast - FF3E:20:2001:DB8::43 - {0xFF,0x3E,0x00,0x20,0x20,0x01,0x0D,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43}, - // MT3 - 2001:660:382:14:335:600:8014:9153 - {0x20,0x01,0x06,0x60,0x03,0x82,0x00,0x14,0x03,0x35,0x06,0x00,0x80,0x14,0x91,0x53} -}; -#else -extern const char DestIpv6Addr[ADDR_MAX][16]; -#endif - -typedef int ral_enb_instance_t; - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/* List of link action types */ -TYPEDEF_BITMAP8(MIH_C_LINK_AC_TYPE_LIST); - - - - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -//extern struct ral_lte_priv *ralpriv; - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -#endif - diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/rrc_d_types.h b/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/rrc_d_types.h deleted file mode 100755 index 3324f6237e..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/INCLUDE/rrc_d_types.h +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef __RRC_DTYPES_H__ -#define __RRC_DTYPES_H__ - -# error "Remove inclusion" -//typedef unsigned char uint8_t; -//typedef unsigned short uint16_t; -//typedef unsigned int uint32_t; - - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/eNB_lte_user.conf b/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/eNB_lte_user.conf deleted file mode 100755 index 4e14bcf4a9..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/eNB_lte_user.conf +++ /dev/null @@ -1,40 +0,0 @@ -#=============================================================================== -# Brief : MIH-User configuration file -# Authors : Carlos Guimaraes <cguimaraes@av.it.pt> -# Bruno Santos <bsantos@av.it.pt> -#------------------------------------------------------------------------------- -# ODTONE - Open Dot Twenty One -# -# Copyright (C) 2009-2012 Universidade Aveiro -# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -# -# This software is distributed under a license. The full license -# agreement can be found in the file LICENSE in this distribution. -# This software may not be copied, modified, sold or distributed -# other than expressed in the named license agreement. -# -# This software is distributed without any warranty. -#=============================================================================== - -## -## User id -## -[user] -id = user - -## -## Commands supported by the MIH-User -## -commands = mih_link_get_parameters, mih_link_configure_thresholds, mih_link_actions, mih_net_ho_candidate_query, mih_net_ho_commit, mih_n2n_ho_query_resources, mih_n2n_ho_commit, mih_n2n_ho_complete, mih_mn_ho_candidate_query, mih_mn_ho_commit, mih_mn_ho_complete - -## -## Port used for communication with MIHF -## -[conf] -port = 1234 - -## -## MIHF configuration. For the default demonstration leave as is. -## -[mihf] -local_port = 1025 diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/link_sap.conf b/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/link_sap.conf deleted file mode 100755 index 4ca476fbbe..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/link_sap.conf +++ /dev/null @@ -1,47 +0,0 @@ -#=============================================================================== -# Brief : Link SAP configuration file -# Authors : Carlos Guimaraes <cguimaraes@av.it.pt> -# Bruno Santos <bsantos@av.it.pt> -#------------------------------------------------------------------------------- -# ODTONE - Open Dot Twenty One -# -# Copyright (C) 2009-2012 Universidade Aveiro -# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -# -# This software is distributed under a license. The full license -# agreement can be found in the file LICENSE in this distribution. -# This software may not be copied, modified, sold or distributed -# other than expressed in the named license agreement. -# -# This software is distributed without any warranty. -#=============================================================================== - -[link] -## -## Link SAP identifier -## -id=link1 - -## -## Link SAP listening -## -port = 1235 - -## -## Link SAP interface technology -## -tec = LTE - -## -## Link SAP interface address -## -link_addr = 00:11:22:33:44:55 - -## -## Comma separated list of the Link SAP supported events -## -event_list = link_detected, link_up, link_down, link_parameters_report, link_going_down, link_handover_imminent, link_handover_complete - -[mihf] -ip=127.0.0.1 -local_port=1025 diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/odtone.conf b/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/odtone.conf deleted file mode 100755 index fd3ef9d859..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/dist/odtone.conf +++ /dev/null @@ -1,71 +0,0 @@ -#=============================================================================== -# Brief : MIHF configuration file -# Authors : Carlos Guimaraes <cguimaraes@av.it.pt> -#------------------------------------------------------------------------------- -# ODTONE - Open Dot Twenty One -# -# Copyright (C) 2009-2012 Universidade Aveiro -# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -# -# This software is distributed under a license. The full license -# agreement can be found in the file LICENSE in this distribution. -# This software may not be copied, modified, sold or distributed -# other than expressed in the named license agreement. -# -# This software is distributed without any warranty. -#=============================================================================== - -[mihf] -## -## This mihf's id -## -## Usage: id = <MIHF ID> -## -id = mihf1 - -## -## Port on localhost that MIH Users and MIH Link SAPs connect to. -## -## Usage: local_port = <port> -## -local_port = 1025 - -## -## Port to which remote peer MIHF connect to -## -## Usage: remote_port = <port> -## -#remote_port = 4551 - -## -## Comma seperated list of remote MIHF's -## -## If you want to test remote MIHF communication add an entry here -## with the IP address of the remote MIHF. -## -## Usage: peers = <mihf id> <ip> <port>, ... -## -#peers = mihf2 0.0.0.0 4552 - -## -## Comma separated list of local MIH User SAPs id's and ports -## -## Usage: users = <user sap id> <port> [<supported commands> <supported queries>], ... -## Note: If no command is specified, the MIHF will assume that the MIH-User -## supports all MIH_***_HO_*** commands and the MIH_Get_Information -## Note: If no query is specified, the MIHF will assume that the MIH-User does -## not support the MIH_Get_Information command. -## -users = user 1234 - -## -## Comma separated list of local MIH Link SAPs id's and ports. -## -## Usage: links = <link sap id> <port> <techonoly type> <interface> [<supported events list> <supported commands list>], ... -## -#links = wifi 1235 802_11 00:11:22:33:44:55, lte 1234 LTE 00:11:22 5 - -## -## Comma separated list of the MIHF's transport protocol -## -transport = udp diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/Jamfile b/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/Jamfile deleted file mode 100755 index ec4608d57a..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/Jamfile +++ /dev/null @@ -1,33 +0,0 @@ -#=============================================================================== -# Brief : MIH-User SAP Application Sample Project Build -# Authors : Carlos Guimaraes <cguimaraes@av.it.pt> -# Bruno Santos <bsantos@av.it.pt> -#------------------------------------------------------------------------------- -# ODTONE - Open Dot Twenty One -# -# Copyright (C) 2009-2012 Universidade Aveiro -# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -# -# This software is distributed under a license. The full license -# agreement can be found in the file LICENSE in this distribution. -# This software may not be copied, modified, sold or distributed -# other than expressed in the named license agreement. -# -# This software is distributed without any warranty. -#=============================================================================== - -project eNB_lte_user - ; - -exe eNB_lte_user - : rg_mih_usr.cpp - ../../lib/odtone//odtone_base - ../../lib/odtone/mih//odtone_mih - ../../lib/odtone/sap//odtone_sap - ; - -install install - : eNB_lte_user - eNB_lte_user.conf - : <location>../../dist - ; diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/dummy_130606.tgz b/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/dummy_130606.tgz deleted file mode 100644 index 11ef083a922376ab0b713c88568902ae7483a5ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108774 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 diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/eNB_lte_user.conf b/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/eNB_lte_user.conf deleted file mode 100755 index 4e14bcf4a9..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/eNB_lte_user.conf +++ /dev/null @@ -1,40 +0,0 @@ -#=============================================================================== -# Brief : MIH-User configuration file -# Authors : Carlos Guimaraes <cguimaraes@av.it.pt> -# Bruno Santos <bsantos@av.it.pt> -#------------------------------------------------------------------------------- -# ODTONE - Open Dot Twenty One -# -# Copyright (C) 2009-2012 Universidade Aveiro -# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -# -# This software is distributed under a license. The full license -# agreement can be found in the file LICENSE in this distribution. -# This software may not be copied, modified, sold or distributed -# other than expressed in the named license agreement. -# -# This software is distributed without any warranty. -#=============================================================================== - -## -## User id -## -[user] -id = user - -## -## Commands supported by the MIH-User -## -commands = mih_link_get_parameters, mih_link_configure_thresholds, mih_link_actions, mih_net_ho_candidate_query, mih_net_ho_commit, mih_n2n_ho_query_resources, mih_n2n_ho_commit, mih_n2n_ho_complete, mih_mn_ho_candidate_query, mih_mn_ho_commit, mih_mn_ho_complete - -## -## Port used for communication with MIHF -## -[conf] -port = 1234 - -## -## MIHF configuration. For the default demonstration leave as is. -## -[mihf] -local_port = 1025 diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/rg_mih_usr.cpp b/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/rg_mih_usr.cpp deleted file mode 100755 index 4084cde793..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/MIH-USER/lte_test_user/rg_mih_usr.cpp +++ /dev/null @@ -1,1358 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include <odtone/base.hpp> -#include <odtone/debug.hpp> -#include <odtone/logger.hpp> -#include <odtone/mih/request.hpp> -#include <odtone/mih/response.hpp> -#include <odtone/mih/indication.hpp> -#include <odtone/mih/confirm.hpp> -#include <odtone/mih/tlv_types.hpp> -#include <odtone/sap/user.hpp> - -#include <boost/utility.hpp> -#include <boost/bind.hpp> -#include <boost/tokenizer.hpp> -#include <boost/foreach.hpp> -#include <boost/format.hpp> - -#include <iostream> -#include <map> -#include <time.h> - -/////////////////////////////////////////////////////////////////////////////// - -// Definition of the scenario to execute -#define NB_OF_RESOURCES 4 // Should not exceed mih_user::_max_link_action_requests -//#define SCENARIO_1 // Sequentially activate and deactivate each resource -#define SCENARIO_2 // Activate all resources, then deactivate all resources -#define NUM_PARM_REPORT 10 - -/////////////////////////////////////////////////////////////////////////////// -// The scenario coded in this MIH-USER is the following (with eRALlteDummy and NASRGDummy executables) -// +--------+ +-----+ -// |MIH_USER| |MIH-F| -// +---+----+ +--+--+ -// | | _current_link_action_request = 0 -// |---------- User_Register.indication ---------------->| (supported_commands) Handler next msg=user_reg_handler -// | | -// |---------- Capability_Discover.request ------------->| Handler next msg=receive_MIH_Capability_Discover_confirm -// |<--------- Capability_Discover.confirm --------------| (success) -// | | -// |---------- Event_Subscribe.request ----------------->| Handler next msg=receive_MIH_Event_Subscribe_confirm -// |<--------- Event_Subscribe.confirm ------------------| (success) -// | | -// ------------------------------------------------------------------------------------------------------------------------ -// Scenario 1: Sequentially activate and deactivate each resource -// ------------------------------------------------------------------------------------------------------------------------ -// | | -// |---------- Link_Actions.request -------------------->| (activate-resources[_current_link_action_request]) -// | | Handler next msg=receive_MIH_Link_Actions_confirm -// |<--------- Link_Actions.confirm ---------------------| (success) -// |---------- Link_Actions.request -------------------->| (deactivate-resources[_current_link_action_request]) -// | | Handler next msg=receive_MIH_Link_Actions_confirm -// | | _current_link_action_request = _current_link_action_request + 1 -// |<--------- Link_Actions.confirm ---------------------| (success) -// | . | -// | . | -// | . | -// | | -// ------------------------------------------------------------------------------------------------------------------------ -// Scenario 2: Activate all resources, then deactivate all resources -// ------------------------------------------------------------------------------------------------------------------------ -// | | -// |---------- Link_Actions.request -------------------->| (activate-resources[_current_link_action_request]) -// | | Handler next msg=receive_MIH_Link_Actions_confirm -// | | _current_link_action_request = _current_link_action_request + 1 -// |<--------- Link_Actions.confirm ---------------------| (success) -// | . | -// | . | -// | . | _current_link_action_request = 0 -// |---------- Link_Actions.request -------------------->| (deactivate-resources[_current_link_action_request]) -// | | Handler next msg=receive_MIH_Link_Actions_confirm -// | | _current_link_action_request = _current_link_action_request + 1 -// |<--------- Link_Actions.confirm ---------------------| (success) -// | . | -// | . | -// | . | -// | | -// ------------------------------------------------------------------------------------------------------------------------ -// | | -// |---------- Event_Unsubscribe.request --------------->| Handler next msg=receive_MIH_Event_Unsubscribe_confirm -// |<--------- Event_Subscribe.confirm ------------------| (success) -// | | -// | | -/////////////////////////////////////////////////////////////////////////////// - -static const char* const kConf_MIH_Commands = "user.commands"; - -/////////////////////////////////////////////////////////////////////////////// - -namespace po = boost::program_options; - -using odtone::uint; -using odtone::ushort; -using odtone::sint8; - -odtone::logger log_("[mih_usr]", std::cout); - -/////////////////////////////////////////////////////////////////////////////// - -//----------------------------------------------------------------------------- -void __trim(odtone::mih::octet_string &str, const char chr) -//----------------------------------------------------------------------------- -{ - str.erase(std::remove(str.begin(), str.end(), chr), str.end()); -} -//----------------------------------------------------------------------------- -template <class T> std::string StringOf(T object) { -//----------------------------------------------------------------------------- - std::ostringstream os; - os << object; - return(os.str()); -} -//----------------------------------------------------------------------------- -std::string getTimeStamp4Log() -//----------------------------------------------------------------------------- -{ - std::stringstream ss (std::stringstream::in | std::stringstream::out); - struct timespec time_spec; - unsigned int time_now_micros; - unsigned int time_now_s; - clock_gettime (CLOCK_REALTIME, &time_spec); - time_now_s = (unsigned int) time_spec.tv_sec % 3600; - time_now_micros = (unsigned int) time_spec.tv_nsec/1000; - ss << time_now_s << ':' << time_now_micros; - return ss.str(); -} -//----------------------------------------------------------------------------- -std::string status2string(odtone::mih::status statusP){ -//----------------------------------------------------------------------------- - switch (statusP.get()) { - case odtone::mih::status_success: return "SUCCESS";break; - case odtone::mih::status_failure: return "UNSPECIFIED_FAILURE";break; - case odtone::mih::status_rejected: return "REJECTED";break; - case odtone::mih::status_authorization_failure: return "AUTHORIZATION_FAILURE";break; - case odtone::mih::status_network_error: return "NETWORK_ERROR";break; - default: return "UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string link_down_reason2string(odtone::mih::link_dn_reason reasonP){ -//----------------------------------------------------------------------------- - switch (reasonP.get()) { - case odtone::mih::link_dn_reason_explicit_disconnect: return "DN_REASON_EXPLICIT_DISCONNECT";break; - case odtone::mih::link_dn_reason_packet_timeout: return "DN_REASON_PACKET_TIMEOUT";break; - case odtone::mih::link_dn_reason_no_resource: return "DN_REASON_NO_RESOURCE";break; - case odtone::mih::link_dn_reason_no_broadcast: return "DN_REASON_NO_BROADCAST";break; - case odtone::mih::link_dn_reason_authentication_failure: return "DN_REASON_AUTHENTICATION_FAILURE";break; - case odtone::mih::link_dn_reason_billing_failure: return "DN_REASON_BILLING_FAILURE";break; - default: return "DN_REASON_UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string link_going_down_reason2string(odtone::mih::link_gd_reason reasonP){ -//----------------------------------------------------------------------------- - switch (reasonP.get()) { - case odtone::mih::link_gd_reason_explicit_disconnect: return "GD_REASON_EXPLICIT_DISCONNECT";break; - case odtone::mih::link_gd_reason_link_parameter_degrading: return "GD_REASON_PARAMETER_DEGRADING";break; - case odtone::mih::link_gd_reason_low_power: return "GD_REASON_LOW_POWER";break; - case odtone::mih::link_gd_reason_no_resource: return "GD_REASON_NO_RESOURCE";break; - default: return "GD_REASON_UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string evt2string(odtone::mih::mih_evt_list evtP){ -//----------------------------------------------------------------------------- - std::string s; - if(evtP.get(odtone::mih::mih_evt_link_detected)) s = std::string("DETECTED "); - if(evtP.get(odtone::mih::mih_evt_link_up)) s += "UP "; - if(evtP.get(odtone::mih::mih_evt_link_down)) s += "DOWN "; - if(evtP.get(odtone::mih::mih_evt_link_parameters_report)) s += "PARAMETERS_REPORT "; - if(evtP.get(odtone::mih::mih_evt_link_going_down)) s += "GOING_DOWN "; - if(evtP.get(odtone::mih::mih_evt_link_handover_imminent)) s += "HANDOVER_IMMINENT "; - if(evtP.get(odtone::mih::mih_evt_link_handover_complete)) s += "HANDOVER_COMPLETE "; - if(evtP.get(odtone::mih::mih_evt_link_pdu_transmit_status)) s += "PDU_TRANSMIT_STATUS "; - return s; -} -//----------------------------------------------------------------------------- -std::string cmd2string(odtone::mih::mih_cmd_list cmdP){ -//----------------------------------------------------------------------------- - std::string s; - if(cmdP.get(odtone::mih::mih_cmd_link_get_parameters)) s = std::string("Link_Get_Parameters "); - if(cmdP.get(odtone::mih::mih_cmd_link_configure_thresholds)) s += "Link_Configure_Thresholds "; - if(cmdP.get(odtone::mih::mih_cmd_link_actions)) s += "Link_Actions "; - if(cmdP.get(odtone::mih::mih_cmd_net_ho_candidate_query)) s += "Net_HO_Candidate_Query "; - if(cmdP.get(odtone::mih::mih_cmd_net_ho_commit)) s += "Net_HO_Commit "; - if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_query_resources)) s += "N2N_HO_Query_Resources "; - if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_commit)) s += "N2N_HO_Commit "; - if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_complete)) s += "N2N_HO_Complete "; - if(cmdP.get(odtone::mih::mih_cmd_mn_ho_candidate_query)) s += "MN_HO_Candidate_Query "; - if(cmdP.get(odtone::mih::mih_cmd_mn_ho_commit)) s += "MN_HO_Commit "; - if(cmdP.get(odtone::mih::mih_cmd_mn_ho_complete)) s += "MN_HO_Complete "; - return s; -} -//----------------------------------------------------------------------------- -std::string link_type2string(const odtone::mih::link_type& lt) -//----------------------------------------------------------------------------- -{ - switch (lt.get()) { - case odtone::mih::link_type_gsm: return "GSM"; break; - case odtone::mih::link_type_gprs: return "GPRS"; break; - case odtone::mih::link_type_edge: return "EDGE"; break; - case odtone::mih::link_type_ethernet: return "Ethernet"; break; - case odtone::mih::link_type_wireless_other: return "Other"; break; - case odtone::mih::link_type_802_11: return "IEEE 802.11"; break; - case odtone::mih::link_type_cdma2000: return "CDMA-2000"; break; - case odtone::mih::link_type_umts: return "UMTS"; break; - case odtone::mih::link_type_cdma2000_hrpd: return "CDMA-2000-HRPD"; break; - case odtone::mih::link_type_lte: return "LTE"; break; - case odtone::mih::link_type_802_16: return "IEEE 802.16"; break; - case odtone::mih::link_type_802_20: return "IEEE 802.20"; break; - case odtone::mih::link_type_802_22: return "IEEE 802.22"; break; - default: break; - } - return "Unknown link type"; -} -//----------------------------------------------------------------------------- -std::string link_addr2string(const odtone::mih::link_addr *addr) -//----------------------------------------------------------------------------- -{ - if (const odtone::mih::mac_addr *la = boost::get<odtone::mih::mac_addr>(addr)) { - return la->address(); - } - else if (const odtone::mih::l2_3gpp_3g_cell_id *la = boost::get<odtone::mih::l2_3gpp_3g_cell_id>(addr)) { - char plmn[16]; - sprintf(plmn, "%hhx:%hhx:%hhx", la->plmn_id[0], la->plmn_id[1], la->plmn_id[2]); - return str(boost::format("%s %d") % plmn % la->_cell_id); - } - else if (const odtone::mih::l2_3gpp_2g_cell_id *la = boost::get<odtone::mih::l2_3gpp_2g_cell_id>(addr)) { - char plmn[16]; - sprintf(plmn, "%hhx:%hhx:%hhx", la->plmn_id[0], la->plmn_id[1], la->plmn_id[2]); - return str(boost::format("%s %d %d") % plmn % la->_lac % la->_ci); - } - else if (const odtone::mih::l2_3gpp_addr *la = boost::get<odtone::mih::l2_3gpp_addr>(addr)) { - return la->value; - } - else if (const odtone::mih::l2_3gpp2_addr *la = boost::get<odtone::mih::l2_3gpp2_addr>(addr)) { - return la->value; - } - else if (const odtone::mih::other_l2_addr *la = boost::get<odtone::mih::other_l2_addr>(addr)) { - return la->value; - } - return "null"; -} -//----------------------------------------------------------------------------- -std::string l2_3gpp_3g_cell_id2string(odtone::mih::l2_3gpp_3g_cell_id& addr) -//----------------------------------------------------------------------------- -{ - char buffer[256]; - int index = 0; - - index += std::sprintf(&buffer[index], "plmn: -%hhx--%hhx--%hhx-\n", addr.plmn_id[0], addr.plmn_id[1], addr.plmn_id[2]); - index += std::sprintf(&buffer[index], "cell_id: %hhx\n", addr._cell_id); - return buffer; -} -//----------------------------------------------------------------------------- -std::string link_id2string(odtone::mih::link_id linkP) -//----------------------------------------------------------------------------- -{ - std::string s; - s = link_type2string(linkP.type.get()) + " " + link_addr2string(&linkP.addr); - return s; -} -//----------------------------------------------------------------------------- -std::string ip_addr2string(odtone::mih::ip_addr ip_addrP) { -//----------------------------------------------------------------------------- - std::string s; - switch (ip_addrP.type()) { - case odtone::mih::ip_addr::ipv4: s = "ipv4 "; break; - case odtone::mih::ip_addr::ipv6: s = "ipv6 "; break; - default: s = "Unkown type "; - } - s += ip_addrP.address(); - return s; -} -//----------------------------------------------------------------------------- -std::string ip_tuple2string(odtone::mih::ip_tuple ip_tupleP) { -//----------------------------------------------------------------------------- - char buffer[128]; - std::snprintf(buffer, 128, "%s/%d", ip_addr2string(ip_tupleP.ip).c_str(), ip_tupleP.port_val); - return buffer; -} -//----------------------------------------------------------------------------- -std::string ip_proto2string(odtone::mih::proto ip_protoP) { -//----------------------------------------------------------------------------- - switch (ip_protoP.get()) { - case odtone::mih::proto_tcp: return "TCP"; - case odtone::mih::proto_udp: return "UDP"; - default: break; - } - return "Unknown IP protocol"; -} -// TEMP : next 2 functions are commented to restore flow_id as a uint32 -// full structure will be updated later -/*//----------------------------------------------------------------------------- -std::string flow_id2string(odtone::mih::flow_id flowP) { -//----------------------------------------------------------------------------- - std::string s; - odtone::mih::ip_tuple ip; - ip = flowP.src; - s = "SRC = " + ip_tuple2string(flowP.src); - s += ", DST = " + ip_tuple2string(flowP.dst); - s += ", PROTO = " + ip_proto2string(flowP.transport); - return s; -} -//----------------------------------------------------------------------------- -std::string flow_id2string(odtone::mih::link_ac_param link_ac_paramP) { -//----------------------------------------------------------------------------- - if (odtone::mih::resource_desc *res = boost::get<odtone::mih::resource_desc>(&link_ac_paramP.param)) { - return flow_id2string(res->fid); - } - else if (odtone::mih::flow_attribute *flow = boost::get<odtone::mih::flow_attribute>(&link_ac_paramP.param)) { - return flow_id2string(flow->id); - } - return "null"; -}*/ -//----------------------------------------------------------------------------- -std::string link_ac_result2string(odtone::mih::link_ac_result resultP) -//----------------------------------------------------------------------------- -{ - switch (resultP.get()) { - case odtone::mih::link_ac_success: return "SUCCESS"; break; - case odtone::mih::link_ac_failure: return "FAILURE"; break; - case odtone::mih::link_ac_refused: return "REFUSED"; break; - case odtone::mih::link_ac_incapable: return "INCAPABLE"; break; - default: break; - } - return "Unknown action result"; -} -//----------------------------------------------------------------------------- -std::string link_actions_req2string(odtone::mih::link_action_req link_act_reqP) { -//----------------------------------------------------------------------------- - std::string s; - - s = link_id2string(link_act_reqP.id); - - if(link_act_reqP.action.type == odtone::mih::link_ac_type_none) s += ", AC_TYPE_NONE"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_disconnect) s += ", AC_TYPE_DISCONNECT"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_low_power) s += ", AC_TYPE_LOW_POWER"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_down) s += ", AC_TYPE_POWER_DOWN"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_up) s += ", AC_TYPE_POWER_UP"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_flow_attr) s += ", AC_TYPE_FLOW_ATTR"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_activate_resources) s += ", AC_TYPE_ACTIVATE_RESOURCES"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_deactivate_resources) s += ", AC_TYPE_DEACTIVATE_RESOURCES"; - - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_data_fwd_req)) s += ", AC_ATTR_DATA_FWD_REQ"; - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_scan)) s += ", AC_ATTR_SCAN"; - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_res_retain)) s += ", AC_ATTR_RES_RETAIN"; - - s += ", " + StringOf(link_act_reqP.ex_time) + " ms"; - return s; -} -//----------------------------------------------------------------------------- -std::string net_type_addr_list2string(boost::optional<odtone::mih::net_type_addr_list> ntalP) { -//----------------------------------------------------------------------------- - std::string s; - odtone::mih::link_id link_id; - - for (odtone::mih::net_type_addr_list::iterator i = ntalP->begin(); i != ntalP->end(); i++) - { - link_id.type = boost::get<odtone::mih::link_type>(i->nettype.link); - link_id.addr = i->addr; - if (i != ntalP->begin()) { - s += " / "; - } - s += link_id2string(link_id); - } - - return s; -} - -/** - * Parse supported commands. - * - * @param cfg Configuration options. - * @return An optional list of supported commands. - */ -boost::optional<odtone::mih::mih_cmd_list> parse_supported_commands(const odtone::mih::config &cfg) -{ - using namespace boost; - - odtone::mih::mih_cmd_list commands; - - std::map<std::string, odtone::mih::mih_cmd_list_enum> enum_map; - enum_map["mih_link_get_parameters"] = odtone::mih::mih_cmd_link_get_parameters; - enum_map["mih_link_configure_thresholds"] = odtone::mih::mih_cmd_link_configure_thresholds; - enum_map["mih_link_actions"] = odtone::mih::mih_cmd_link_actions; - enum_map["mih_net_ho_candidate_query"] = odtone::mih::mih_cmd_net_ho_candidate_query; - enum_map["mih_net_ho_commit"] = odtone::mih::mih_cmd_net_ho_commit; - enum_map["mih_n2n_ho_query_resources"] = odtone::mih::mih_cmd_n2n_ho_query_resources; - enum_map["mih_n2n_ho_commit"] = odtone::mih::mih_cmd_n2n_ho_commit; - enum_map["mih_n2n_ho_complete"] = odtone::mih::mih_cmd_n2n_ho_complete; - enum_map["mih_mn_ho_candidate_query"] = odtone::mih::mih_cmd_mn_ho_candidate_query; - enum_map["mih_mn_ho_commit"] = odtone::mih::mih_cmd_mn_ho_commit; - enum_map["mih_mn_ho_complete"] = odtone::mih::mih_cmd_mn_ho_complete; - - std::string tmp = cfg.get<std::string>(kConf_MIH_Commands); - __trim(tmp, ' '); - - char_separator<char> sep1(","); - tokenizer< char_separator<char> > list_tokens(tmp, sep1); - - BOOST_FOREACH(std::string str, list_tokens) { - if(enum_map.find(str) != enum_map.end()) { - commands.set((odtone::mih::mih_cmd_list_enum) enum_map[str]); - } - } - - return commands; -} - -/////////////////////////////////////////////////////////////////////////////// -/** - * This class provides an implementation of an IEEE 802.21 MIH-User. - */ -class mih_user : boost::noncopyable { -public: - /** - * Construct the MIH-User. - * - * @param cfg Configuration options. - * @param io The io_service object that the MIH-User will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io); - - /** - * Destruct the MIH-User. - */ - ~mih_user(); - -protected: - /** - * User registration handler. - * - * @param cfg Configuration options. - * @param ec Error Code. - */ - void user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec); - /** - * Default MIH event handler. - * - * @param msg Received event notification. - * @param ec Error code. - */ - void event_handler(odtone::mih::message& msg, const boost::system::error_code& ec); - /** - * MIH receive message handler. - * - * @param msg Received message. - * @param ec Error code. - */ - void receive_handler(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_User_Register_indication(const odtone::mih::config& cfg); - - void send_MIH_Capability_Discover_request(void); - void receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg); - - void send_MIH_Event_Subscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt); - void receive_MIH_Event_Subscribe_confirm(odtone::mih::message& msg); - - void send_MIH_Event_Unsubscribe_request(void); - void send_MIH_Event_Unsubscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt); - void receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg); - - void send_MIH_Link_Actions_request(const odtone::mih::link_id& link, odtone::mih::link_ac_type type); - void receive_MIH_Link_Actions_confirm(odtone::mih::message& msg); - void receive_MIH_Link_Parameters_Report(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_Link_Configure_Thresholds_request(odtone::mih::message& msg, const boost::system::error_code& ec); - void receive_MIH_Link_Configure_Thresholds_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - -private: - odtone::sap::user _mihf; /**< User SAP helper. */ - odtone::mih::id _mihfid; /**< MIHF destination ID. */ - odtone::mih::id _mihuserid; /**< MIH_USER ID. */ - - odtone::mih::ip_addr _mihf_ip; /**< MIHF IP address */ - odtone::mih::port _mihf_lport; /**< MIHF local port number */ - - odtone::mih::link_id_list _link_id_list; /**< List of network link identifiers */ - odtone::mih::mih_evt_list _subs_evt_list; /**< List of subscribed link events */ - - odtone::mih::link_ac_type _last_link_action_type; - odtone::uint _current_link_action_request, _nb_of_link_action_requests; - odtone::uint link_threshold_request, link_measures_request, link_measures_counter; - odtone::mih::link_id rcv_link_id; - - static const odtone::uint _max_link_action_requests = 4; - - void receive_MIH_Link_Detected_indication(odtone::mih::message& msg); - - void receive_MIH_Link_Up_indication(odtone::mih::message& msg); - - void receive_MIH_Link_Down_indication(odtone::mih::message& msg); - - void receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg); - -}; - -//----------------------------------------------------------------------------- -mih_user::mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io) - : _mihf(cfg, io, boost::bind(&mih_user::event_handler, this, _1, _2)), - _last_link_action_type(odtone::mih::link_ac_type_none), - _current_link_action_request(0), _nb_of_link_action_requests(NB_OF_RESOURCES) -//----------------------------------------------------------------------------- -{ - - odtone::mih::octet_string user_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_id); - _mihuserid.assign(user_id.c_str()); - - odtone::mih::octet_string dest_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_dest); - _mihfid.assign(dest_id.c_str()); - - odtone::mih::octet_string src = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIHF_Ip); - boost::asio::ip::address ip = boost::asio::ip::address::from_string(src); - if (ip.is_v4()) { - odtone::mih::ip_addr ip_addr(odtone::mih::ip_addr::ipv4, src); - _mihf_ip = ip_addr; - } - else if (ip.is_v6()) { - odtone::mih::ip_addr ip_addr(odtone::mih::ip_addr::ipv6, src); - _mihf_ip = ip_addr; - } - - _mihf_lport = cfg.get<odtone::mih::port>(odtone::sap::kConf_MIHF_Local_Port); - - //_nb_of_link_action_requests = NB_OF_RESOURCES; - if (_nb_of_link_action_requests > _max_link_action_requests) { - _nb_of_link_action_requests = _max_link_action_requests; - } - - _link_id_list.clear(); - _subs_evt_list.clear(); - link_threshold_request = 0; - link_measures_request =0; - link_measures_counter =0; - log_(0, "[MSC_NEW]["+getTimeStamp4Log()+"][MIH-USER="+_mihuserid.to_string()+"]\n"); - - // Send MEDIEVAL specific MIH_User_Register.indication message to the MIH-F - mih_user::send_MIH_User_Register_indication(cfg); -} - -//----------------------------------------------------------------------------- -mih_user::~mih_user() -//----------------------------------------------------------------------------- -{ -} - -//----------------------------------------------------------------------------- -void mih_user::user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH-User register result: ", ec.message(), "\n"); - - // - // Let's fire a capability discover request to get things moving - // - mih_user::send_MIH_Capability_Discover_request(); -} - -//----------------------------------------------------------------------------- -void mih_user::event_handler(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - switch (msg.mid()) { - case odtone::mih::indication::link_detected: - mih_user::receive_MIH_Link_Detected_indication(msg); - break; - - case odtone::mih::indication::link_up: - mih_user::receive_MIH_Link_Up_indication(msg); - break; - - case odtone::mih::indication::link_down: - mih_user::receive_MIH_Link_Down_indication(msg); - break; - - case odtone::mih::indication::link_going_down: - mih_user::receive_MIH_Link_Going_Down_indication(msg); - break; - - case odtone::mih::indication::link_handover_imminent: - log_(0, "MIH-User has received a local event \"link_handover_imminent\""); - break; - - case odtone::mih::indication::link_handover_complete: - log_(0, "MIH-User has received a local event \"link_handover_complete\""); - break; - - case odtone::mih::indication::link_parameters_report: - //log_(0, "MIH-User has received a local event \"link_parameters_report\""); - mih_user::receive_MIH_Link_Parameters_Report(msg, ec); - if (link_threshold_request == 0){ - mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec); - link_threshold_request =1; - } else if (link_threshold_request == 1){ - link_measures_counter ++; - // Stop measures after 5 reports - if (link_measures_counter == NUM_PARM_REPORT){ - mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec); - } - } - break; - - case odtone::mih::indication::link_pdu_transmit_status: - log_(0, "MIH-User has received a local event \"link_pdu_transmit_status\""); - break; - - case odtone::mih::confirm::link_configure_thresholds: - mih_user::receive_MIH_Link_Configure_Thresholds_confirm(msg, ec); - break; - - default: - log_(0, "MIH-User has received UNKNOWN local event"); - break; - } -} - -//----------------------------------------------------------------------------- -void mih_user::receive_handler(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - switch (msg.mid()) { - - case odtone::mih::confirm::capability_discover: - mih_user::receive_MIH_Capability_Discover_confirm(msg); - break; - - case odtone::mih::confirm::event_subscribe: - mih_user::receive_MIH_Event_Subscribe_confirm(msg); - break; - - case odtone::mih::confirm::event_unsubscribe: - mih_user::receive_MIH_Event_Unsubscribe_confirm(msg); - break; - - case odtone::mih::confirm::link_actions: - mih_user::receive_MIH_Link_Actions_confirm(msg); - - break; - default: - log_(0, "MIH-User has received UNKNOWN message (", msg.mid(), ")\n"); - break; - } -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Detected_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Detected.indication - RECEIVED - Begin\n"); - - odtone::mih::link_det_info_list ldil; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_det_info_list(ldil); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Detected.indication --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - // TODO: for each link_det_info in the list {display LINK_DET_INFO} - - log_(0, "MIH_Link_Detected.indication - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Up_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Up.indication - RECEIVED - Begin\n"); - - odtone::mih::link_tuple_id link; -// odtone::mih::tlv_old_access_router oldAR; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link); -// & odtone::mih::tlv_old_access_router(oar); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Up.indication --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str(), "\n"); - - log_(0, "MIH_Link_Up.indication - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Down_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Down.indication - RECEIVED - Begin\n"); - - odtone::mih::link_tuple_id link; - boost::optional<odtone::mih::link_addr> addr; - odtone::mih::link_dn_reason ldr; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_old_access_router(addr) - & odtone::mih::tlv_link_dn_reason(ldr); - -// log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Down.indication\\n"+link_down_reason2string(ldr).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - - //Display message parameters - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str(), "\n"); -// log_(0, " - LINK_DN_REASON - Link down reason: ", link_down_reason2string(ldr).c_str(), "\n"); - - log_(0, "MIH_Link_Down.indication - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Going_Down.indication - RECEIVED - Begin\n"); - - odtone::mih::link_tuple_id link; - odtone::mih::link_gd_reason lgd; - odtone::mih::link_ac_ex_time ex_time; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_time_interval(ex_time) - & odtone::mih::tlv_link_gd_reason(lgd); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Going_Down.indication\\n"+link_going_down_reason2string(lgd).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str()); - log_(0, " - Time Interval:", (ex_time/256)); - log_(0, " - LINK_GD_REASON - Link going down reason: ", link_going_down_reason2string(lgd).c_str(), "\n"); - - log_(0, "MIH_Link_Going_Down.indication - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Parameters_Report(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id link; - odtone::mih::link_param_rpt_list lprl; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_link_param_rpt_list(lprl); - - log_(0, ""); - log_(0, "MIH_Link_Parameters_Report.indication - RECEIVED - Begin"); - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Parameters_Report.indication --->]["+msg.destination().to_string()+"]\n"); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(link).c_str()); - log_(0, "MIH_Link_Parameters_Report.indication - End"); -} - - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_User_Register_indication(const odtone::mih::config& cfg) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - boost::optional<odtone::mih::mih_cmd_list> supp_cmd = parse_supported_commands(cfg); - - m << odtone::mih::indication(odtone::mih::indication::user_register) - & odtone::mih::tlv_command_list(supp_cmd); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_User_Register.indication --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::user_reg_handler, this, boost::cref(cfg), _2)); - - log_(0, "MIH_User_Register.indication - SENT (towards its local MIHF)\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Capability_Discover_request(void) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - m << odtone::mih::request(odtone::mih::request::capability_discover); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Capability_Discover.request --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH_Capability_Discover.request - SENT (towards its local MIHF)\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Capability_Discover.confirm - RECEIVED - Begin\n"); - - odtone::mih::status st; - boost::optional<odtone::mih::net_type_addr_list> ntal; - boost::optional<odtone::mih::mih_evt_list> evt; - boost::optional<odtone::mih::mih_cmd_list> cmd; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_net_type_addr_list(ntal) - & odtone::mih::tlv_event_list(evt) - & odtone::mih::tlv_command_list(cmd); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Capability_Discover.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - "\\nNet type addr list=" + net_type_addr_list2string(ntal).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - if (evt) { - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - if (cmd) { - log_(0, " - MIH_CMD_LIST - Command List: ", cmd2string(cmd.get()).c_str()); - } - if (ntal) { - log_(0, " - LIST(NET_TYPE_ADDR) - Network Types and Link Address: ", net_type_addr_list2string(ntal).c_str()); - //Store link address - for (odtone::mih::net_type_addr_list::iterator i = ntal->begin(); i != ntal->end(); i++) - { - rcv_link_id.addr = i->addr; - rcv_link_id.type = boost::get<odtone::mih::link_type>(i->nettype.link); - } - } - log_(0, ""); - - // - // event subscription - // - // For every interface the MIHF sent in the - // Capability_Discover.response send an Event_Subscribe.request - // for all availabe events - // - if (ntal && evt) { - _subs_evt_list = evt.get(); // save the list of subscribed link events - for (odtone::mih::net_type_addr_list::iterator i = ntal->begin(); i != ntal->end(); i++) { - if (i->nettype.link.which() == 1) - { - odtone::mih::link_tuple_id li; - - li.addr = i->addr; - li.type = boost::get<odtone::mih::link_type>(i->nettype.link); - _link_id_list.push_back(li); // save the link identifier of the network interface - - mih_user::send_MIH_Event_Subscribe_request(li, evt.get()); - } - } - } - - log_(0, "MIH_Capability_Discover.confirm - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Event_Subscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - m << odtone::mih::request(odtone::mih::request::event_subscribe) - & odtone::mih::tlv_link_identifier(li) - & odtone::mih::tlv_event_list(evt); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Event_Subscribe.request"+ - "\\nLink="+link_id2string(li).c_str()+ - "\\nEvent list="+evt2string(evt).c_str()+ - " --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH-User has sent Event_Subscribe.request to ", m.destination().to_string()); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(li).c_str()); - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt).c_str(), "\n"); - - log_(0, "MIH_Event_Subscribe.request - SENT\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Event_Subscribe_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Event_Subscribe.confirm(", msg.tid(), ") - RECEIVED - Begin\n"); - - odtone::mih::status st; - odtone::mih::link_tuple_id link; - boost::optional<odtone::mih::mih_evt_list> evt; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_event_list(evt); - - if (evt) { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Subscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } else { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Subscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(link).c_str()); - if (evt) { - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - log_(0, ""); - - //mih_user::send_MIH_Link_Actions_request(link, odtone::mih::link_ac_type_link_activate_resources); - log_(0, "TEMP : Resource scenario deactivated\n"); - - log_(0, "MIH_Event_Subscribe.confirm - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Event_Unsubscribe_request(void) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id li; - - // For every interface the MIH user received in the - // Capability_Discover.confirm, send an Event_Unsubscribe.request - // for all subscribed events - for (odtone::mih::link_id_list::iterator i = _link_id_list.begin(); i != _link_id_list.end(); i++) { - li.type = i->type; - li.addr = i->addr; - mih_user::send_MIH_Event_Unsubscribe_request(li, _subs_evt_list); - } -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Event_Unsubscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - m << odtone::mih::request(odtone::mih::request::event_unsubscribe) - & odtone::mih::tlv_link_identifier(li) - & odtone::mih::tlv_event_list(evt); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Event_Unsubscribe.request"+ - "\\nLink="+link_id2string(li).c_str()+ - "\\nEvent list="+evt2string(evt).c_str()+ - " --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH-User has sent Event_Unsubscribe.request to ", m.destination().to_string()); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(li).c_str()); - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt).c_str(), "\n"); - - log_(0, "MIH_Event_Unsubscribe.request - SENT\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Event_Unsubscribe.confirm(", msg.tid(), ") - RECEIVED - Begin\n"); - - odtone::mih::status st; - odtone::mih::link_tuple_id link; - boost::optional<odtone::mih::mih_evt_list> evt; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_event_list(evt); - - if (evt) { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Unsubscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } else { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Unsubscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(link).c_str()); - if (evt) { - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - log_(0, ""); - - log_(0, "MIH_Event_Unsubscribe.confirm - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Actions_request(const odtone::mih::link_id& link, odtone::mih::link_ac_type type) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - odtone::mih::link_action_list lal; - odtone::mih::link_action_req link_act_req; - - link_act_req.id = link; - link_act_req.action.type = type; - - _last_link_action_type = type; - - // Initialize resource parameters - odtone::mih::resource_desc res; - - res.lid = link; // Link identifier - res.data_rate = 128000; // bit rate - res.jumbo = false; // jumbo disable - res.multicast = false; // multicast disable - - odtone::mih::qos qos; // Class Of Service - qos.value = 56; - res.qos_val = qos; - res.fid = 555 + _current_link_action_request; - -// // Flow identifier -// res.fid.src.ip = _mihf_ip; -// res.fid.src.port_val = _mihf_lport; -// -// if (mih_user::_current_link_action_request == 0) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "2001:0660:0382:0014:0335:0600:8014:9150"); // DUMMY -// } -// else if (mih_user::_current_link_action_request == 1) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "2001:0660:0382:0014:0335:0600:8014:9151"); // DUMMY -// } -// else if (mih_user::_current_link_action_request == 2) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "FF3E:0020:2001:0DB8:0000:0000:0000:0043"); // DUMMY -// res.multicast = true; -// } -// else if (mih_user::_current_link_action_request == 3) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "2001:0660:0382:0014:0335:0600:8014:9153"); // DUMMY -// } -// res.fid.dst.port_val = 1235; // DUMMY -// res.fid.transport = odtone::mih::proto_udp; - - link_act_req.action.param.param = res; - - link_act_req.ex_time = 0; - - lal.push_back(link_act_req); - - m << odtone::mih::request(odtone::mih::request::link_actions) - & odtone::mih::tlv_link_action_list(lal); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Link_Actions.request\\n"+link_actions_req2string(link_act_req)+" --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH-User has sent Link_Actions.request to ", m.destination().to_string()); - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str()); - log_(0, " - FLOW_ID - Flow identifier: ", res.fid); -//TEMP log_(0, " - FLOW_ID - Flow identifier: ", flow_id2string(link_act_req.action.param).c_str()); - log_(0, " - LINK_ACTIONS - Link Actions: " + link_actions_req2string(link_act_req) + "\n"); - - log_(0, "MIH_Link_Actions.request - SENT\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Actions_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Actions.confirm - RECEIVED - Begin\n"); - - odtone::mih::status st; - boost::optional<odtone::mih::link_action_rsp_list> larl; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_action_rsp_list(larl); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Actions.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - if (larl) { - log_(0, " - LINK ACTION RSP LIST - Length:", larl.get().size()); - for (odtone::mih::link_action_rsp_list::iterator i = larl->begin(); i != larl->end(); i++) - { - log_(0, "\tLINK_ID: ", link_id2string(i->id).c_str(), - ", LINK_AC_RESULT: ", link_ac_result2string(i->result).c_str()); - } - } - log_(0, ""); - - // 1st scenario: Sequentially activate and deactivate each resource -#ifdef SCENARIO_1 - if (larl) { - odtone::mih::link_action_rsp *rsp = &larl->front(); - if (_current_link_action_request < _nb_of_link_action_requests) { - if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) { - if (rsp->result.get() == odtone::mih::link_ac_success) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources); - _current_link_action_request += 1; - } - } - else if (_last_link_action_type == odtone::mih::link_ac_type_link_deactivate_resources) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_activate_resources); - } - } - else { // Ends the scenario - mih_user::send_MIH_Event_Unsubscribe_request(); - } - } -#endif // SCENARIO_1 - -#ifdef SCENARIO_2 - // 2nd scenario: Activate all resources, then deactivate all resources - if (larl.get().size() > 0) { - odtone::mih::link_action_rsp *rsp = &larl->front(); - if (++_current_link_action_request < _nb_of_link_action_requests) { - if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_activate_resources); - } - else if (_last_link_action_type == odtone::mih::link_ac_type_link_deactivate_resources) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources); - } - } - else if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) { - _current_link_action_request = 0; - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources); - } - else { // Ends the scenario - mih_user::send_MIH_Event_Unsubscribe_request(); - } - } -#endif // SCENARIO_2 - - log_(0, "MIH_Link_Actions.confirm - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Configure_Thresholds_request(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - odtone::mih::threshold th; - std::vector<odtone::mih::threshold> thl; - - odtone::mih::link_tuple_id lti; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0,""); - log_(0, "send_MIH_Link_Configure_Thresholds_request - Begin"); - - //link_tuple_id - lti.type = rcv_link_id.type; - lti.addr = rcv_link_id.addr; - - //local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(lti.addr); - - //List of the link threshold parameters - odtone::mih::link_cfg_param_list lcpl; - odtone::mih::link_cfg_param lcp; - odtone::mih::link_param_lte lp; - - //link_param_gen_data_rate = 0, /**< Data rate. */ - //link_param_gen_signal_strength = 1, /**< Signal strength. */ - //link_param_gen_sinr = 2, /**< SINR. */ - //link_param_gen_throughput = 3, /**< Throughput. */ - //link_param_gen_packet_error_rate = 4, /**< Packet error rate. */ - lp = odtone::mih::link_param_lte_bandwidth; - - lcp.type = lp; - - if ( link_measures_request ==0){ - // Set Timer Interval (in ms) - lcp.timer_interval = 3000; - //th_action_normal = 0, /**< Set normal threshold. */ - //th_action_one_shot = 1, /**< Set one-shot threshold. */ - //th_action_cancel = 2 /**< Cancel threshold. */ - lcp.action = odtone::mih::th_action_normal; - link_measures_request = 1; - } else if ( link_measures_request==1){ - // Set Timer Interval (in ms) - lcp.timer_interval = 0; - lcp.action = odtone::mih::th_action_cancel; - link_measures_request = 0; - } - - //above_threshold = 0, /**< Above threshold. */ - //below_threshold = 1, /**< Below threshold. */ - th.threshold_val = 0; - th.threshold_x_dir = odtone::mih::threshold::above_threshold; - - thl.push_back(th); - lcp.threshold_list = thl; - lcpl.push_back(lcp); - - m << odtone::mih::request(odtone::mih::request::link_configure_thresholds) - & odtone::mih::tlv_link_identifier(lti) - & odtone::mih::tlv_link_cfg_param_list(lcpl); - - m.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihuserid.to_string() +"][--- MIH_Link_Configure_Thresholds.request\\nlink="+ - // link_tupple_id2string(lti).c_str() + - link_id2string(lti).c_str()+ - " --->]["+_mihfid.to_string()+"]\n"); - _mihf.async_send(m, boost::bind(&mih_user::event_handler, this, _1, _2)); - - - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(lti).c_str()); - - log_(0, "\t- LINK CFG PARAM LIST - Length: ", lcpl.size()); - - //if(lp == odtone::mih::link_param_gen_data_rate) {log_(0, "\t Generic link parameter DATA RATE ");} - //if(lp == odtone::mih::link_param_gen_signal_strength) {log_(0, "\t Generic link parameter SIGNAL STRENGTH");} - //if(lp == odtone::mih::link_param_gen_sinr) {log_(0, "\t Generic link parameter SINR");} - //if(lp == odtone::mih::link_param_gen_throughput) {log_(0, "\t Generic link parameter THROUGHPUT");} - if(lp == odtone::mih::link_param_lte_bandwidth) {log_(0, "\t LTE link parameter BANDWIDTH");} - - log_(0, "\t- TIMER INTERVAL - Value: ", lcp.timer_interval); - - if(lcp.action == odtone::mih::th_action_normal) {log_(0, "\t Normal Threshold");} - if(lcp.action == odtone::mih::th_action_one_shot) {log_(0, "\t One Shot Threshold");} - if(lcp.action == odtone::mih::th_action_cancel) {log_(0, "\t Threshold to be canceled");} - - log_(0, "\t Threshold value: ", th.threshold_val); - - if(th.threshold_x_dir == odtone::mih::threshold::below_threshold) {log_(0, "\t Threshold direction BELOW");} - if(th.threshold_x_dir == odtone::mih::threshold::above_threshold) {log_(0, "\t Threshold direction ABOVE");} - - log_(0, "send_MIH_Link_Configure_Thresholds_request - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Configure_Thresholds_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - log_(0, ""); - log_(0, "receive_MIH_Link_Configure_Thresholds_confirm - Begin"); - - // T odtone::uint iter; - // T odtone::mih::status st; - - //boost::optional<odtone::mih::link_cfg_status_list> lcsl; - // Todtone::mih::link_cfg_status_list lcsl; - // Todtone::mih::link_cfg_status lcp; - //odtone::mih::link_param_gen lp; - - // T odtone::mih::link_tuple_id lti; - - //msg >> odtone::mih::confirm() - // & odtone::mih::tlv_status(st) - // & odtone::mih::tlv_link_identifier(lti) - // & odtone::mih::tlv_link_cfg_status_list(lcsl); - - - log_(0, "receive_MIH_Link_Configure_Thresholds_confirm - End"); - log_(0,""); -} - -//----------------------------------------------------------------------------- -int main(int argc, char** argv) -//----------------------------------------------------------------------------- -{ - odtone::setup_crash_handler(); - - try { - boost::asio::io_service ios; - - // declare MIH Usr available options - po::options_description desc(odtone::mih::octet_string("MIH Usr Configuration")); - desc.add_options() - ("help", "Display configuration options") - (odtone::sap::kConf_File, po::value<std::string>()->default_value("mih_usr.conf"), "Configuration file") - (odtone::sap::kConf_Receive_Buffer_Len, po::value<uint>()->default_value(4096), "Receive buffer length") - (odtone::sap::kConf_Port, po::value<ushort>()->default_value(1234), "Listening port") - (odtone::sap::kConf_MIH_SAP_id, po::value<std::string>()->default_value("user"), "MIH-User ID") - (kConf_MIH_Commands, po::value<std::string>()->default_value(""), "MIH-User supported commands") - (odtone::sap::kConf_MIHF_Ip, po::value<std::string>()->default_value("127.0.0.1"), "Local MIHF IP address") - (odtone::sap::kConf_MIHF_Local_Port, po::value<ushort>()->default_value(1025), "Local MIHF communication port") - (odtone::sap::kConf_MIH_SAP_dest, po::value<std::string>()->default_value("mihf1"), "MIHF destination"); - - odtone::mih::config cfg(desc); - cfg.parse(argc, argv, odtone::sap::kConf_File); - - if (cfg.help()) { - std::cerr << desc << std::endl; - return EXIT_SUCCESS; - } - - mih_user usr(cfg, ios); - - ios.run(); - - } catch(std::exception& e) { - log_(0, "exception: ", e.what()); - } -} - -// EOF //////////////////////////////////////////////////////////////////////// - diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/Makefile b/openair3/RAL-LTE/LTE_RAL_ENB/Makefile deleted file mode 100755 index a536f76b20..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -# lines starting with the pound sign are comments. -# -# These things are options that you might need -# to tweak. - - -# You can modify the below as well, but probably -# won't need to. -INTERFACE_DIR=../INTERFACE-802.21 -INCLUDE_DIR=INCLUDE -SRC_DIR=SRC -# external directories for ioctl -RRC_DIR := $(OPENAIR2_DIR)/RRC/CELLULAR -NAS_DIR := $(OPENAIR2_DIR)/NAS/DRIVER/CELLULAR/NASRG - -# SVN version -#SVNREV = -D'SVN_REV="$(shell svnversion -n .)"' -SVNREV = -D'SVN_REV="1"' - -CC = gcc - -#CFLAGS = -Wall -g -I$(SRC_DIR) -I$(INTERFACE_DIR)/INCLUDE -I$(INCLUDE_DIR) \ -# -DMIH_C_MEDIEVAL_EXTENSIONS -DMSCGEN_PYTOOL -DMIH_USER_CONTROL $(SVNREV) - -CFLAGS = -Wall -g -I$(SRC_DIR) -I$(INTERFACE_DIR)/INCLUDE -I$(INCLUDE_DIR) -DMIH_C_MEDIEVAL_EXTENSIONS -DMIH_USER_CONTROL $(SVNREV) -CFLAGS += -I$(NAS_DIR) -I$(RRC_DIR) - -LDFLAGS = -L$(INTERFACE_DIR)/LIB -lmih_c-802.21 -lrt - -ERAL_OBJS += $(SRC_DIR)/lteRALenb_mih_msg.o -ERAL_OBJS += $(SRC_DIR)/lteRALenb_rrc_msg.o -ERAL_OBJS += $(SRC_DIR)/lteRALenb_thresholds.o -ERAL_OBJS += $(SRC_DIR)/lteRALenb_parameters.o -ERAL_OBJS += $(SRC_DIR)/lteRALenb_action.o -ERAL_OBJS += $(SRC_DIR)/lteRALenb_subscribe.o -ERAL_OBJS += $(SRC_DIR)/lteRALenb_process.o -ERAL_OBJS += $(SRC_DIR)/lteRALenb_main.o - -OBJS = $(ERAL_OBJS) - - -E_RAL_EXE = LTE_RAL_ENB - -EXECUTABLE = interface $(E_RAL_EXE) - -# "all" is the default target. Simply make it point to myprogram. - -all: $(EXECUTABLE) - -interface : -# -(cd $(INTERFACE_DIR) && make clean && make) - -(cd $(INTERFACE_DIR) && make) - -cleaninterface : - -(cd $(INTERFACE_DIR) && make clean) - -$(E_RAL_EXE) : $(ERAL_OBJS) - $(CC) -o $@ $^ $(LDFLAGS) - -%.o: %.c Makefile - @echo Compiling $< - @$(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) -o $@ $< - -clean: - -find . -name "*.o" -delete - -find . -name "*.*~" -delete - -find . -name "*~" -delete -# -rm -f $(M_RAL_EXE) $(M_NAS_EXE) -# -rm -f $(E_RAL_EXE) $(E_NAS_EXE) diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_action.c b/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_action.c deleted file mode 100755 index 651d5f47b7..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_action.c +++ /dev/null @@ -1,890 +0,0 @@ -/***************************************************************************** - * Eurecom OpenAirInterface 3 - * Copyright(c) 2012 Eurecom - * - * Source eRAL_action.c - * - * Version 0.1 - * - * Date 07/03/2012 - * - * Product MIH RAL LTE - * - * Subsystem MIH link action request messages processing - * - * Authors Michelle Wetterwald, Lionel Gauthier, Frederic Maurel - * - * Description - * - *****************************************************************************/ -#define LTE_RAL_ENB -#define LTE_RAL_ENB_ACTION_C - -#include <assert.h> -#include "lteRALenb.h" - - -/****************************************************************************/ -/******************* G L O C A L D E F I N I T I O N S *****************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -static MIH_C_LINK_ACTION_T g_link_action; - -static const char* g_link_action_type_str[] = { - "MIH_C_LINK_AC_TYPE_NONE", - "MIH_C_LINK_AC_TYPE_LINK_DISCONNECT", - "MIH_C_LINK_AC_TYPE_LINK_LOW_POWER", - "MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN", - "MIH_C_LINK_AC_TYPE_LINK_POWER_UP", -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - "MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR", - "MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES", - "MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES" -#endif -}; - - -/**************************************************************************** - ** ** - ** Name: eRAL_action_request() ** - ** ** - ** Description: Processes the Link_Action.request message and sends a ** - ** Link_Action.confirm message to the MIHF. ** - ** ** - ** Inputs: msgP: Pointer to the received message ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_link_action ** - ** ** - ***************************************************************************/ -void eRAL_action_request(ral_enb_instance_t instanceP, MIH_C_Message_Link_Action_request_t* msgP) -{ - MIH_C_STATUS_T status; - MIH_C_LINK_AC_TYPE_T link_action_type; - MIH_C_LINK_AC_RESULT_T link_action_result; - int link_action_done = 0; - - - rrc_ral_connection_reconfiguration_req_t connection_reconfiguration_req_t; - MessageDef *message_p = NULL; - - message_p = itti_alloc_new_message (TASK_RAL_ENB, RRC_RAL_CONNECTION_RECONFIGURATION_REQ); - memset(&connection_reconfiguration_req_t, 0, sizeof(rrc_ral_connection_reconfiguration_req_t)); - // copy transaction id - // connection_reconfiguration_req_t.transaction_id = msgP->header.transaction_id; - - - memcpy(&g_link_action, &msgP->primitive.LinkAction, sizeof(MIH_C_LINK_ACTION_T)); - - status = MIH_C_STATUS_SUCCESS; - link_action_type = msgP->primitive.LinkAction.link_ac_type; - link_action_result = MIH_C_LINK_AC_RESULT_SUCCESS; - - /* - * Read link action attributs - * -------------------------- - */ - // if (msgP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_LINK_SCAN) - // { - // /* - // * Link scan operation request - Not supported by the network side: - // * No measurements - // */ - // LOG_D(RAL_ENB, " ACTION ATTRIBUTE MIH_C_BIT_LINK_AC_ATTR_LINK_SCAN: REFUSED\n"); - // link_action_result = MIH_C_LINK_AC_RESULT_REFUSED; - // eRAL_send_link_action_confirm(instanceP, &msgP->header.transaction_id, - // &status, - // NULL, - // &link_action_result); - // } - - // if (msgP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_LINK_RES_RETAIN) - // { - // /* - // * Link resource retain operation request - Not supported by the - // * network side. - // */ - // LOG_D(RAL_ENB, " ACTION ATTRIBUTE MIH_C_BIT_LINK_AC_ATTR_LINK_RES_RETAIN: REFUSED\n"); - // link_action_result = MIH_C_LINK_AC_RESULT_REFUSED; - // eRAL_send_link_action_confirm(instanceP, &msgP->header.transaction_id, - // &status, - // NULL, - // &link_action_result); - // } - - // if (msgP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_DATA_FWD_REQ) - // { - // /* - // * Data forward operation request - Not supported by the network side. - // */ - // LOG_D(RAL_ENB, " ACTION ATTRIBUTE MIH_C_BIT_LINK_AC_ATTR_DATA_FWD_REQ: REFUSED\n"); - // link_action_result = MIH_C_LINK_AC_RESULT_REFUSED; - // eRAL_send_link_action_confirm(instanceP, &msgP->header.transaction_id, - // &status, - // NULL, - // &link_action_result); - // } - - /* - * Read link action request - * ------------------------ - * Requested actions that are not supported or currently in progress - * are refused. - */ - if (eRAL_action_is_in_progress(instanceP, &status, - &link_action_result, - link_action_type)) { - LOG_D(RAL_ENB, " Link action request %s is not supported or currently in progress\n", g_link_action_type_str[link_action_type]); - } else { - LOG_D(RAL_ENB, " %s ACTION REQUESTED: %s\n", __FUNCTION__, g_link_action_type_str[link_action_type]); - - switch (link_action_type) { - case MIH_C_LINK_AC_TYPE_NONE: - LOG_D(RAL_ENB, " %s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_NONE: NO ACTION\n", __FUNCTION__); - break; - -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - - case MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR: - /* - * Provide the mark and multicast configuration to be set up - * for the data flow - */ - g_enb_ral_obj[instanceP].pending_req_ac_result = eRAL_action_link_flow_attr(instanceP); - link_action_done = 1; - break; - - case MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES: - /* - * Configure and activate a data flow - */ - g_enb_ral_obj[instanceP].pending_req_ac_result = eRAL_action_link_activate_resources(instanceP); - link_action_done = 1; - break; - - case MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES: - /* - * Deactivate a previously activated data flow - */ - g_enb_ral_obj[instanceP].pending_req_ac_result = eRAL_action_link_deactivate_resources(instanceP); - link_action_done = 1; - break; -#endif // MIH_C_MEDIEVAL_EXTENSIONS - - case MIH_C_LINK_AC_TYPE_LINK_DISCONNECT: - - /* - * Disconnect the link connection directly - */ - case MIH_C_LINK_AC_TYPE_LINK_LOW_POWER: - - /* - * Cause the link to adjust its battery power level to be - * low power consumption - Not supported by the network side - */ - case MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN: - - /* - * Cause the link to power down and turn off the radio - * - Not supported by the network side - */ - case MIH_C_LINK_AC_TYPE_LINK_POWER_UP: - LOG_D(RAL_ENB, "%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_POWER_UP\n", __FUNCTION__); - - if (g_enb_ral_obj[instanceP].mih_supported_link_action_list & (1 << MIH_C_LINK_AC_TYPE_LINK_POWER_UP)) { - // Activation requested - check it is not already active - if(g_enb_ral_obj[instanceP].pending_req_action & MIH_C_LINK_AC_TYPE_LINK_POWER_UP) { - // if (g_enb_ral_obj[instanceP].state == CONNECTED) { - // LOG_D(RAL_ENB, "Activation requested, but interface already active ==> NO OP\n"); - // mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - // } else { - g_enb_ral_obj[instanceP].pending_req_action = g_enb_ral_obj[instanceP].pending_req_action | MIH_C_LINK_AC_TYPE_LINK_POWER_UP; - // g_enb_ral_obj[instanceP].cell_id = g_enb_ral_obj[instanceP].meas_cell_id[0]; // Default cell #0 - Next, choose cell with best conditions - LOG_D(RAL_ENB, "Activation requested to NAS interface on cell %d\n", g_enb_ral_obj[instanceP].cell_id); - // RAL_process_NAS_message(IO_OBJ_CNX, IO_CMD_ADD, g_enb_ral_obj[instanceP].cell_id); - // } - } else { - g_enb_ral_obj[instanceP].pending_req_action |= MIH_C_LINK_AC_TYPE_LINK_POWER_UP; - /* g_enb_ral_obj[instanceP].cell_id = g_enb_ral_obj[instanceP].meas_cell_id[0];*/ // Default cell #0 - Next, choose cell with best conditions - message_p = itti_alloc_new_message (TASK_RAL_ENB, RRC_RAL_CONNECTION_RECONFIGURATION_REQ); - memset(&connection_reconfiguration_req_t, 0, sizeof(rrc_ral_connection_reconfiguration_req_t)); - // copy transaction id - connection_reconfiguration_req_t.transaction_id = msgP->header.transaction_id; - - connection_reconfiguration_req_t.link_action.link_ac_type = msgP->primitive.LinkAction.link_ac_type; - connection_reconfiguration_req_t.link_action.link_ac_attr = msgP->primitive.LinkAction.link_ac_attr; - connection_reconfiguration_req_t.link_action.link_ac_param = msgP->primitive.LinkAction.link_ac_param; - - memcpy (&message_p->ittiMsg, (void *) &connection_reconfiguration_req_t, sizeof(rrc_ral_connection_reconfiguration_req_t)); - itti_send_msg_to_task (TASK_RRC_ENB, instanceP, message_p); - - /* LOG_D(RAL_ENB, "Total data volume0 %d\n", (g_enb_ral_obj[instanceP].totalDataVolume[0]/1000)); - LOG_D(RAL_ENB, "Total data volume1 %d\n", (g_enb_ral_obj[instanceP].totalDataVolume[1]/1000)); - LOG_D(RAL_ENB, "RLC Buffer Occupancy 0 %d\n", (g_enb_ral_obj[instanceP].rlcBufferOccupancy[0])); - LOG_D(RAL_ENB, "RLC Buffer Occupancy 1 %d\n", (g_enb_ral_obj[instanceP].rlcBufferOccupancy[1])); - */ - } - } else { - LOG_D(RAL_ENB, "[mRAL]: command POWER UP not available \n\n"); - // link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - // mRAL_send_link_action_confirm(instanceP, &msgP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - - break; - - default: - LOG_E(RAL_ENB, "%s Invalid LinkAction.link_ac_type %d\n", - __FUNCTION__, link_action_type); - status = MIH_C_STATUS_UNSPECIFIED_FAILURE; - } - } - - /* Return link action confirmation to the MIH-F */ - if (link_action_done) { - g_enb_ral_obj[instanceP].pending_req_transaction_id = msgP->header.transaction_id; - g_enb_ral_obj[instanceP].pending_req_status = MIH_C_STATUS_SUCCESS; - eRAL_send_link_action_confirm(instanceP, &g_enb_ral_obj[instanceP].pending_req_transaction_id, - &g_enb_ral_obj[instanceP].pending_req_status, - NULL, - &g_enb_ral_obj[instanceP].pending_req_ac_result); - } else if (status == MIH_C_STATUS_SUCCESS) { - eRAL_send_link_action_confirm(instanceP, &msgP->header.transaction_id, - &status, - NULL, - &link_action_result); - } else { - eRAL_send_link_action_confirm(instanceP, &msgP->header.transaction_id, - &status, - NULL, - NULL); - } - - g_enb_ral_obj[instanceP].pending_req_action = 0; -} - -/**************************************************************************** - ** ** - ** Name: eRAL_action_save_flow_id() ** - ** ** - ** Description: Save connection identifier and data of the specified data ** - ** flow into the list of active data flows. ** - ** ** - ** Inputs: flowId: The data flow identifier ** - ** cnxid: The connection identifier ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: The index of the specified data flow in ** - ** the list of active data flows. ** - ** -1 if the list is full. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRAL_action_save_flow_id(ral_enb_instance_t instanceP, MIH_C_FLOW_ID_T* flowId, int cnxid) -{ - return eRAL_action_set_channel_id(instanceP, flowId, cnxid); -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/**************************************************************************** - ** Name: eRAL_action_set_channel_id() ** - ** ** - ** Description: Set the Connection identifier and store data of the ** - ** specified data flow in the list of active data flows. ** - ** Inputs: flowId: The data flow identifier ** - ** cnxid: The connection identifier ** - ** Outputs: None ** - ** Return: The index of the specified data flow in ** - ** the list of active data flows. ** - ** -1 if the list is full. ** - ***************************************************************************/ -int eRAL_action_set_channel_id (ral_enb_instance_t instanceP, MIH_C_FLOW_ID_T* flowId, int cnxid) -{ - // char addr[128]; - //char port[8]; - int f_ix; - - assert(cnxid != 0); - - for (f_ix = 0; f_ix < ACTION_MAX_FLOW; f_ix++) { - if (g_flows.flow[f_ix].cnxid > 0) continue; - - g_flows.flow[f_ix].cnxid = cnxid; - g_flows.flow_id[f_ix] = (int)flowId; - g_flows.n_flows += 1; - - // Modified Michelle -#warning "TO DO DestIpv6Addr ?" - //memcpy((char*)&(DestIpv6Addr[0][16]), addr, 16); - eRAL_process_mt_addr_to_l2id(&g_flows.flow[f_ix].addr[8], - &g_flows.flow[f_ix].l2id[0]); - - /* MIH_C_TRANSPORT_ADDR_VALUE2String(&flowId->dest_addr.ip_addr.address, addr); - memcpy((char*)&(g_flows.flow[f_ix].addr), addr, 16); - eRAL_process_mt_addr_to_l2id(&g_flows.flow[f_ix].addr[8], - &g_flows.flow[f_ix].l2id[0]); - MIH_C_PORT2String(&flowId->dest_addr.port, port); - g_flows.flow[f_ix].port = strtol(port, (char**) NULL, 16); - g_flows.flow[f_ix].proto = flowId->transport_protocol;*/ - return f_ix; - } - - return (-1); -} - -/**************************************************************************** - ** Name: eRAL_action_get_channel_id() ** - ** ** - ** Description: Returns the Connection identifier of the specified data ** - ** flow. ** - ** Inputs: flowId: The data flow identifier ** - ** Others: None ** - ** Outputs: cnxid: The connection identifier allocated to the ** - ** specified data flow. ** - ** Return: The index of the specified data flow in ** - ** the list of active data flows. ** - ** -1 if no any connection identifier exists ** - ** for the specified data flow. ** - ** Others: None ** - ***************************************************************************/ -int eRAL_action_get_channel_id (ral_enb_instance_t instanceP, MIH_C_FLOW_ID_T* flowId, int* cnxid) -{ - //char addr[128]; - //char port[8]; - //unsigned int dp; - int f_ix; - - // MIH_C_TRANSPORT_ADDR_VALUE2String(&flowId->dest_addr.ip_addr.address, addr); - // MIH_C_PORT2String(&flowId->dest_addr.port, port); - // dp = strtol(port, (char**) NULL, 16); - - for (f_ix = 0; f_ix < ACTION_MAX_FLOW; f_ix++) { - /* if (!eRAL_process_cmp_mt_addr((const char*)addr, (const char*)g_flows.flow[f_ix].l2id)) continue; - if (g_flows.flow[f_ix].port != dp) continue; - if (g_flows.flow[f_ix].proto != flowId->transport_protocol) continue;*/ - if (g_flows.flow_id[f_ix] != *flowId) continue; - - *cnxid = g_flows.flow[f_ix].cnxid; - return f_ix; - } - - return (-1); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_action_del_channel_id() ** - ** ** - ** Description: Remove the data flow stored at the specified index in the ** - ** list of active data flows. ** - ** ** - ** Inputs: fix: Index of the data flow in the list ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: The number of the remaining data flows in ** - ** the list. ** - ** -1 if the specified index is out of the ** - ** boundary of the list. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRAL_action_del_channel_id (ral_enb_instance_t instanceP, int fix) -{ - if (fix < ACTION_MAX_FLOW) { - g_flows.n_flows -= 1; - memset (&g_flows.flow[fix], 0, sizeof (struct Data_flow)); - return g_flows.n_flows; - } - - return (-1); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_action_is_in_progress() ** - ** ** - ** Description: Checks if an action request is supported and whether it ** - ** is currently in progress. ** - ** ** - ** Inputs: action: Type of link action ** - ** Others: g_link_action, ralpriv ** - ** ** - ** Outputs: status: MIH request status ** - ** ac_status: Action request status ** - ** Return: 1 if the request is not supported or is ** - ** currently in progress and the resource is ** - ** already in the required state. 0 otherwise.** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRAL_action_is_in_progress(ral_enb_instance_t instanceP, MIH_C_STATUS_T* status, - MIH_C_LINK_AC_RESULT_T* ac_status, - MIH_C_LINK_AC_TYPE_T action) -{ - /* Check whether the action link command is supported */ - if (!(g_enb_ral_obj[instanceP].mih_supported_link_command_list & MIH_C_BIT_LINK_ACTION)) { - *status = MIH_C_STATUS_REJECTED; - LOG_D(RAL_ENB,"THE LINK ACTION is not in the list\n"); - return 1; - } - - *status = MIH_C_STATUS_SUCCESS; - - /* Check whether the action request is supported */ - if (g_enb_ral_obj[instanceP].mih_supported_link_action_list & (1 << action)) { - /* Check whether another action request is currently in progress */ - if ((g_enb_ral_obj[instanceP].pending_req_action) && (g_enb_ral_obj[instanceP].pending_req_action != action)) { - /* Another action request is in progress: - * Do not process new request before completion of this one */ - LOG_D(RAL_ENB,"THE LINK ACTION is pending\n"); - *ac_status = MIH_C_LINK_AC_RESULT_REFUSED; - return 1; - } - - /* The action request is supported and no other request is in progress: - * Go ahead and process the request */ - - LOG_D(RAL_ENB,"THE LINK ACTION is not pending\n"); - return 0; - } - - LOG_D(RAL_ENB,"THE LINK ACTION is not supported\n"); - /* The link action request is not supported */ - *ac_status = MIH_C_LINK_AC_RESULT_INCAPABLE; - return 1; -} - -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -/**************************************************************************** - ** ** - ** Name: eRAL_action_link_flow_attr() ** - ** ** - ** Description: Processes the link flow attribut action request. ** - ** ** - ** Inputs: None ** - ** Others: g_link_action ** - ** ** - ** Outputs: None ** - ** Return: MIH_C_LINK_AC_RESULT_SUCCESS if action has ** - ** been successfully processed. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -MIH_C_LINK_AC_RESULT_T eRAL_action_link_flow_attr(ral_enb_instance_t instanceP) -//TODO -{ - MIH_C_FLOW_ATTRIBUTE_T *flow = &g_link_action.link_ac_param._union.flow_attribute; - int mt_ix, ch_ix, f_ix; - int cnxid; - - /* Get the connection identifier */ - f_ix = eRAL_action_get_channel_id(instanceP, &flow->flow_id, &cnxid); - - if (f_ix < 0) { - LOG_D(RAL_ENB, " No RB allocated for this data flow\n"); - return MIH_C_LINK_AC_RESULT_REFUSED; - } - - /* Get MT and RB channel identifiers */ - if (eRAL_process_find_channel(instanceP, cnxid, &mt_ix, &ch_ix) != 0) { - /* Unicast data flow */ - LOG_D(RAL_ENB, " %s: Unicast MT's address = %s\n", __FUNCTION__, - eRAL_process_mt_addr_to_string(g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_addr)); - } else { - /* Multicast data flow */ - LOG_D(RAL_ENB, " %s: Multicast MT's address = %s\n", __FUNCTION__, - eRAL_process_mt_addr_to_string(g_enb_ral_obj[instanceP].mcast.mc_group_addr)); - } - - if (flow->choice_mark_qos) { - LOG_D(RAL_ENB, " Mark QoS enabled\n"); - //TODO ??? - } - - if (flow->choice_mark_drop_eligibility) { - LOG_D(RAL_ENB, " Mark drop eligibility enabled\n"); - //TODO ??? - } - - /* Link action successfully processed */ - g_enb_ral_obj[instanceP].pending_req_action = MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR; - return MIH_C_LINK_AC_RESULT_SUCCESS; -} - -/**************************************************************************** - ** ** - ** Name: eRAL_action_link_activate_resources() ** - ** ** - ** Description: Processes the link activate resource action request. ** - ** ** - ** Inputs: None ** - ** Others: g_link_action ** - ** ** - ** Outputs: None ** - ** Return: MIH_C_LINK_AC_RESULT_SUCCESS if action has ** - ** been successfully processed. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -MIH_C_LINK_AC_RESULT_T eRAL_action_link_activate_resources(ral_enb_instance_t instanceP) -{ - //--------------------------------------------------------------------------- - MIH_C_RESOURCE_DESC_T *res = &g_link_action.link_ac_param._union.resource_desc; - MIH_C_COS_T classIdDL = 0; - MIH_C_COS_T classIdUL = 0; - MIH_C_LINK_DATA_RATE_T resBitrateDL = 0; - MIH_C_LINK_DATA_RATE_T resBitrateUL = 0; - MIH_C_BOOLEAN_T multicast = MIH_C_BOOLEAN_FALSE; - - /* TODO: To be initialized downlink/uplink */ - if (res->choice_qos) { - MIH_C_QOS_T *qos = &(res->_union_qos.qos); - - if (qos->choice) { - classIdDL = qos->_union.cos; - classIdUL = qos->_union.cos; - } - } - - if (res->choice_link_data_rate) { - resBitrateDL = res->_union_link_data_rate.link_data_rate; - resBitrateUL = res->_union_link_data_rate.link_data_rate; - } - - /* end TODO */ - - if (res->choice_multicast_enable) { - multicast = res->_union_multicast_enable.multicast_enable; - } - - /* - * Get the Care-of Address (MT address): - * The destination address is contained into the MIH_C_FLOW_ID structure - * within the MIH_C_RESOURCE_DESC parameters of the request. - */ - char mt_addr[128]; - //original code: int len = MIH_C_TRANSPORT_ADDR_VALUE2String(&res->flow_id.dest_addr.ip_addr.address, mt_addr); - - MIH_C_TRANSPORT_ADDR_VALUE_T mihc_transport_addr_value; - MIH_C_TRANSPORT_ADDR_VALUE_set(&mihc_transport_addr_value, (unsigned char*)"2001:660:382:14:335:600:8014:9150", strlen("2001:660:382:14:335:600:8014:9150")); - - int len = MIH_C_TRANSPORT_ADDR_VALUE2String(&mihc_transport_addr_value, mt_addr); - //int len = MIH_C_TRANSPORT_ADDR_VALUE2String(&DestIpv6Addr[0][16], mt_addr); - - if ( (len > 0) && (len < 128)) { - LOG_D(RAL_ENB, " %s: MT's address = %s\n", __FUNCTION__, eRAL_process_mt_addr_to_string((unsigned char*)mt_addr)); - } else { - LOG_E(RAL_ENB, "%s : IP Address is NOT valid (len=%d)\n", __FUNCTION__, len); - return MIH_C_LINK_AC_RESULT_FAILURE; - } - -#if 0 - char mt_addr[128]; - - if (res->link_id.link_addr.choice == MIH_C_CHOICE_3GPP_3G_CELL_ID) { - char link_addr[128]; - int len = MIH_C_LINK_ADDR2String(&res->link_id.link_addr, link_addr); - - if ( (len > 0) && (len <= 128) ) { - int i; - LOG_D(RAL_ENB, " %s : Link address = %s\n", __FUNCTION__, link_addr); - - for (i=0; i < len; i++) { - if (link_addr[i] == '=') break; - } - - strncpy(mt_addr, &link_addr[i+2], 16); - LOG_D(RAL_ENB, " %s : MT address = %s\n", __FUNCTION__, mt_addr); - } else { - LOG_E(RAL_ENB, "%s : Link address is NOT valid (len=%d)\n", __FUNCTION__, len); - return MIH_C_LINK_AC_RESULT_FAILURE; - } - } else { - LOG_E(RAL_ENB, "%s : Link address is NOT valid (type=%d, not 3GPP_3G_CELL_ID)\n", - __FUNCTION__, res->link_id.link_addr.choice); - return MIH_C_LINK_AC_RESULT_FAILURE; - } - -#endif - - /* - * If the resource has already been activated, check whether it is in the - * required state. - */ - struct ral_lte_channel *currChannel; - int mt_ix, ch_ix, f_ix; - int cnxid; - - /* Get the connection identifier */ - f_ix = eRAL_action_get_channel_id(instanceP, &res->flow_id, &cnxid); - - if (f_ix != -1) { - /* Get MT and RB channel identifiers */ - if (eRAL_process_find_channel(instanceP, cnxid, &mt_ix, &ch_ix) != 0) { - /* Unicast data flow */ - currChannel = &(g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix]); - } else { - /* Multicast data flow */ - assert(multicast == MIH_C_BOOLEAN_TRUE); - currChannel = &(g_enb_ral_obj[instanceP].mcast.radio_channel); - } - - if (currChannel->status == RB_CONNECTED) { - //if (currChannel->status == NAS_CONNECTED) { - /* The resource is already in the required state */ - LOG_D(RAL_ENB, " Link action ACTIVATE_RESOURCES requested while link resource is ALREADY activated\n"); - return MIH_C_LINK_AC_RESULT_SUCCESS; - } - - /* The resource is not in the required state: - * Remove the connection identifier from the list of active resources - * and process the action request again. */ - LOG_D(RAL_ENB, " Resource has been activated but is not in the ACTIVE state\n"); - (void) eRAL_action_del_channel_id(instanceP, f_ix); - } - - MIH_C_LINK_TUPLE_ID_T *ltid; - int is_ready_for_rb_establish = 1; - - if (multicast) { - /* - * Multicast data flow: - */ - mt_ix = RAL_MAX_MT; - ch_ix = 0; - currChannel = &(g_enb_ral_obj[instanceP].mcast.radio_channel); - currChannel->cnx_id = (RAL_MAX_RB_PER_UE*mt_ix)+1; - currChannel->rbId = RAL_DEFAULT_RAB_ID; - currChannel->multicast = 1; - memcpy((char*)&(g_enb_ral_obj[instanceP].mcast.mc_group_addr), mt_addr, 16); - ltid = &(g_enb_ral_obj[instanceP].mcast.ltid); - } else { - /* - * Unicast data flow - */ - /* Get the list of MTs waiting for RB establishment */ -#ifdef RAL_REALTIME - // LG RAL_process_NAS_message(IO_OBJ_CNX, IO_CMD_LIST, 0, 0); - // LG RAL_process_NAS_message(IO_OBJ_RB, IO_CMD_LIST, 0, 0); -#endif - /* Check if the MT is in the list */ - mt_ix = eRAL_process_find_mt_by_addr(instanceP, mt_addr); - - if ( (mt_ix < RAL_MAX_MT) && - (g_enb_ral_obj[instanceP].mt[mt_ix].mt_state == RB_CONNECTED)) { - /* The MT is ready for RB establishment */ - ch_ix = eRAL_process_find_new_channel(instanceP, mt_ix); - - if (ch_ix == RAL_MAX_RB) { - LOG_D(RAL_ENB, " No RB available in MT\n"); - return MIH_C_LINK_AC_RESULT_REFUSED; - } - - currChannel = &(g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix]); - currChannel->cnx_id = (RAL_MAX_RB_PER_UE*mt_ix)+ch_ix+1; - currChannel->rbId = RAL_DEFAULT_RAB_ID + ch_ix; - currChannel->multicast = 0; - LOG_D(RAL_ENB, " mt_ix %d, ch_ix %d, cnx_id %d, rbId %d\n", - mt_ix, ch_ix, currChannel->cnx_id, currChannel->rbId); - memcpy((char *)&(g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_addr), mt_addr, 16); - ltid = &(g_enb_ral_obj[instanceP].mt[mt_ix].ltid); - } else { - /* The MT is NOT ready for RB establishment */ - is_ready_for_rb_establish = 0; - int qos_is_valid = 0; - - LOG_D(RAL_ENB, " Mobile Terminal not ready - Storing request data\n"); - - /* Check validity of QoS parameters */ - if ( (classIdDL < 64) && (classIdUL < 64) ) { - if ( (resBitrateDL <= RAL_BITRATE_320k) - && (resBitrateUL <= RAL_BITRATE_320k) ) { - qos_is_valid = 1; - } else if ( (resBitrateDL >= RAL_BITRATE_384k) - && (resBitrateDL <= RAL_BITRATE_440k) - && (resBitrateUL <= RAL_BITRATE_64k) ) { - qos_is_valid = 1; - } - } - - if (qos_is_valid) { - LOG_D(RAL_ENB, " Received QoS parameters are valid\n"); - } else { - LOG_D(RAL_ENB, " Received QoS parameters are NOT valid - Request will be rejected\n"); - return MIH_C_LINK_AC_RESULT_REFUSED; - } - - currChannel = &(g_enb_ral_obj[instanceP].pending_mt.radio_channel[0]); - currChannel->cnx_id = 0; - currChannel->rbId = 0; - currChannel->multicast = 0; - memcpy((char *)&(g_enb_ral_obj[instanceP].pending_mt.ipv6_addr), mt_addr, 16); - - ltid = &(g_enb_ral_obj[instanceP].pending_mt.ltid); - g_enb_ral_obj[instanceP].pending_req_flag = 1; - - } /* end MT not ready */ - - } /* end unicast data flow */ - - /* Save the current data flow identifier into the list of active data flows */ - if (currChannel->cnx_id != 0) { - f_ix = eRAL_action_set_channel_id(instanceP, &res->flow_id, currChannel->cnx_id); - - if (f_ix < 0) { - LOG_D(RAL_ENB, " No RB available\n"); - return MIH_C_LINK_AC_RESULT_REFUSED; - } - } else { - /* The current request is pending waiting for RB establishment */ - f_ix = 0; - g_enb_ral_obj[instanceP].pending_req_fid = res->flow_id; - } - - /* - * Store resource parameters - */ - int i; - - for (i = 0; i < 2; i++) { - //TODO: int dir = p->qos.value[i].direction; - // TODO: To be initialized downlink/uplink - currChannel->flowId[i] = f_ix; - currChannel->classId[i] = classIdDL; // classIdUL - currChannel->resBitrate[i] = resBitrateDL; // resBitrateUL - //currChannel->meanBitrate[i] = p->qos.value[i].tspec.meanBitrate; - //currChannel->bktDepth[i] = p->qos.value[i].tspec.bucketDepth; - //currChannel->pkBitrate[i] = p->qos.value[i].tspec.peakBitrate; - //currChannel->MTU[i] = p->qos.value[i].tspec.maximumTransmissionUnit; - LOG_D(RAL_ENB, " qos value : DIR %d, flowId %d, classId %d, resBitrate %.1f\n", i , currChannel->flowId[i], currChannel->classId[i], currChannel->resBitrate[i]); - } - - /* Store the link identifier */ - ltid->link_id = res->link_id; - ltid->choice = MIH_C_LINK_TUPLE_ID_CHOICE_LINK_ADDR; - ltid->_union.link_addr.choice = MIH_C_CHOICE_3GPP_3G_CELL_ID; // DUMMY - ltid->_union.link_addr._union._3gpp_3g_cell_id.cell_id = RAL_DEFAULT_CELL_ID; // DUMMY - - /* - * Setup Radio Bearer resources - */ - if (is_ready_for_rb_establish) { - /* Map QoS */ - int mapping_result = eRAL_process_map_qos(instanceP, mt_ix, ch_ix); - - if (mapping_result) { - int rc = -1; -#ifdef RAL_DUMMY - rc = eRAL_NAS_send_rb_establish_request(mt_ix, ch_ix); -#endif -#ifdef RAL_REALTIME - // LG rc = RAL_process_NAS_message(IO_OBJ_RB, IO_CMD_ADD, mt_ix, ch_ix); // FIXME why is this commented? -#endif - - if (rc < 0) { - /* Failed to send RB establishment request */ - return MIH_C_LINK_AC_RESULT_FAILURE; - } - } else { - /* QoS mapping is not supported */ - return MIH_C_LINK_AC_RESULT_REFUSED; - } - } else { - /* Wait for MT coming ready; - * re-try to establish RB upon timer expiration */ -#ifdef RAL_DUMMY - g_enb_ral_obj[instanceP].pending_mt_timer = 5; -#endif -#ifdef RAL_REALTIME - g_enb_ral_obj[instanceP].pending_mt_timer = 300; -#endif - } - - /* Link action successfully processed */ - g_enb_ral_obj[instanceP].pending_req_action = MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES; - return MIH_C_LINK_AC_RESULT_SUCCESS; -} - -/**************************************************************************** - ** ** - ** Name: eRAL_action_link_deactivate_resources() ** - ** ** - ** Description: Processes the link deactivate resource action request. ** - ** ** - ** Inputs: None ** - ** Others: g_link_action ** - ** ** - ** Outputs: None ** - ** Return: MIH_C_LINK_AC_RESULT_SUCCESS if action has ** - ** been successfully processed. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -MIH_C_LINK_AC_RESULT_T eRAL_action_link_deactivate_resources(ral_enb_instance_t instanceP) -{ - MIH_C_RESOURCE_DESC_T *res = &g_link_action.link_ac_param._union.resource_desc; - struct ral_lte_channel *currChannel; - int mt_ix, ch_ix, f_ix; - int cnxid; - - /* Get the connection identifier */ - f_ix = eRAL_action_get_channel_id(instanceP, &res->flow_id, &cnxid); - - if (f_ix < 0) { - LOG_D(RAL_ENB, " Link action DEACTIVATE_RESOURCES requested while link resource is NOT activated\n"); - return MIH_C_LINK_AC_RESULT_SUCCESS; - } - - /* Get MT and RB channel identifiers */ - if (eRAL_process_find_channel(instanceP, cnxid, &mt_ix, &ch_ix) != 0) { - /* Unicast data flow */ - currChannel = &(g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix]); - LOG_D(RAL_ENB, " %s: Unicast MT's address = %s\n", __FUNCTION__, - eRAL_process_mt_addr_to_string(g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_addr)); - } else { - /* Multicast data flow */ - currChannel = &(g_enb_ral_obj[instanceP].mcast.radio_channel); - LOG_D(RAL_ENB, " %s: Multicast MT's address = %s\n", __FUNCTION__, - eRAL_process_mt_addr_to_string(g_enb_ral_obj[instanceP].mcast.mc_group_addr)); - } - - if (currChannel->status == NAS_DISCONNECTED) { - /* The resource is already in the required state */ - LOG_D(RAL_ENB, " Link action request DEACTIVATE_RESOURCES is currently in progress\n"); - return MIH_C_LINK_AC_RESULT_SUCCESS; - } - - /* The resource is not in the required state: - * Remove the connection identifier from the list of active resources - * and go ahead in the request processing. */ - (void) eRAL_action_del_channel_id(instanceP, f_ix); - - int rc = -1; -#ifdef RAL_DUMMY - rc = eRAL_NAS_send_rb_release_request(mt_ix, ch_ix); -#endif -#ifdef RAL_REALTIME - // LG rc = RAL_process_NAS_message(IO_OBJ_RB, IO_CMD_DEL, mt_ix, ch_ix); // FIXME why is this commented? -#endif - - if (rc < 0) { - /* Failed to send RB release request */ - return MIH_C_LINK_AC_RESULT_FAILURE; - } - - /* Link action successfully processed */ - g_enb_ral_obj[instanceP].pending_req_action = MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES; - return MIH_C_LINK_AC_RESULT_SUCCESS; -} - -#endif // MIH_C_MEDIEVAL_EXTENSIONS diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_ioctl.c b/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_ioctl.c deleted file mode 100755 index e102b72af9..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_ioctl.c +++ /dev/null @@ -1,725 +0,0 @@ -/*************************************************************************** - lteRALenb_ioctl.c - description - *************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 1999 - 2013 Eurecom - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information - Openair Admin: openair_admin@eurecom.fr - Openair Tech : openair_tech@eurecom.fr - Forums : http://forums.eurecom.fsr/openairinterface - Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France -*******************************************************************************/ -/*! \file lteRALenb_ioctl.c - * \brief Handling of ioctl for LTE driver in LTE-RAL-ENB - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/******************************************************************************* -#include <sys/ioctl.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <net/if.h> -//#include <linux/ipv6.h> -//#include <linux/in.h> -//#include <linux/in6.h> - -#include <netinet/in.h> - -// -#include "rrc_d_types.h" -//----------------------------------------------------------------------------- -// LTE AS sub-system -//#include "rrc_nas_primitives.h" -//#include "nasrg_constant.h" -//#include "nasrg_iocontrol.h" -//----------------------------------------------------------------------------- -#include "lteRALenb_mih_msg.h" -#include "lteRALenb_constants.h" -#include "lteRALenb_variables.h" -#include "lteRALenb_proto.h" -#include "MIH_C.h" -//#include "MIH_C_Types.h" - -extern struct nas_ioctl gifr; -extern int fd; -extern int s_mgr; //socket with QoS Mgr -extern int init_flag; - -//--------------------------------------------------------------------------- -void print_state(uint8_t state){ -//--------------------------------------------------------------------------- - switch(state){ - case NAS_IDLE:printf("NAS_IDLE\n");return; - case NAS_CX_FACH:printf("NAS_CX_FACH\n");return; - case NAS_CX_DCH:printf("NAS_CX_DCH\n");return; - case NAS_CX_RECEIVED:printf("NAS_CX_RECEIVED\n");return; - case NAS_CX_CONNECTING:printf("NAS_CX_CONNECTING\n");return; - case NAS_CX_RELEASING:printf("NAS_CX_RELEASING\n");return; - case NAS_CX_CONNECTING_FAILURE:printf("NAS_CX_CONNECTING_FAILURE\n");return; - case NAS_CX_RELEASING_FAILURE:printf("NAS_CX_RELEASING_FAILURE\n");return; - case NAS_RB_ESTABLISHING:printf("NAS_RB_ESTABLISHING\n");return; - case NAS_RB_RELEASING:printf("NAS_RB_RELEASING\n");return; - case NAS_RB_ESTABLISHED:printf("NAS_RB_ESTABLISHED\n");return; - - default: printf(" Unknown state\n"); - } -} - -//--------------------------------------------------------------------------- -void RAL_NASinitMTlist(uint8_t *msgrep, int num_mts){ -//--------------------------------------------------------------------------- - int mt_ix, ch_ix; - struct nas_msg_cx_list_reply *list; - - memcpy(g_enb_ral_obj[instanceP].plmn, DefaultPLMN, DEFAULT_PLMN_SIZE); // DUMMY - list=(struct nas_msg_cx_list_reply *)(msgrep+1); - num_mts = msgrep[0]; - for(mt_ix=0; mt_ix<num_mts; ++mt_ix){ - if (list[mt_ix].state != NAS_IDLE){ - g_enb_ral_obj[instanceP].cell_id = list[mt_ix].cellid; - g_enb_ral_obj[instanceP].mt[mt_ix].ue_id = list[mt_ix].lcr; - g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[0]= list[mt_ix].iid6[0]; - g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[1]= list[mt_ix].iid6[1]; - g_enb_ral_obj[instanceP].mt[mt_ix].num_rbs = list[mt_ix].num_rb; - g_enb_ral_obj[instanceP].mt[mt_ix].num_class = list[mt_ix].nsclassifier; - g_enb_ral_obj[instanceP].mt[mt_ix].nas_state = list[mt_ix].state; - if (g_enb_ral_obj[instanceP].mt[mt_ix].num_class>=2) - g_enb_ral_obj[instanceP].mt[mt_ix].mt_state= NAS_CONNECTED; - // enter default rb - ch_ix = 0; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].rbId = RAL_DEFAULT_MC_RAB_ID+1; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].RadioQoSclass = 2; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].cnx_id = (RAL_MAX_RB_PER_UE*mt_ix)+ch_ix+1; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].dscpUL = 0; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].dscpDL = 0; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].nas_state = NAS_CX_DCH; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].status = RB_CONNECTED; - g_enb_ral_obj[instanceP].num_connected_mts++; - //RAL_printMobileData(mt_ix); - DEBUG(" MT%d initialized : address %d %d\n", mt_ix, g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[0], g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[1]); - } - } -} - -//--------------------------------------------------------------------------- -void RAL_NASupdatetMTlist(uint8_t *msgrep, int num_mts){ -//--------------------------------------------------------------------------- - int mt_ix, ch_ix; - struct nas_msg_cx_list_reply *list; - //MIH_C_LINK_TUPLE_ID_T* ltid; - MIH_C_LINK_ADDR_T new_ar; - MIH_C_LINK_DN_REASON_T reason_code; - MIH_C_TRANSACTION_ID_T transaction_id; - int previous_num_class; - - list=(struct nas_msg_cx_list_reply *)(msgrep+1); - num_mts = msgrep[0]; - for(mt_ix=0; mt_ix<num_mts; ++mt_ix){ - // check if MT already known - if ((g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[0]== list[mt_ix].iid6[0])&& - (g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[1]== list[mt_ix].iid6[1])){ - // MT already known - update - g_enb_ral_obj[instanceP].mt[mt_ix].num_rbs = list[mt_ix].num_rb; - previous_num_class = g_enb_ral_obj[instanceP].mt[mt_ix].num_class; - g_enb_ral_obj[instanceP].mt[mt_ix].num_class = list[mt_ix].nsclassifier; - if (g_enb_ral_obj[instanceP].mt[mt_ix].num_class>=2) - g_enb_ral_obj[instanceP].mt[mt_ix].mt_state= RB_CONNECTED; - //check if state has changed - MT disconnected FFS - if ((g_enb_ral_obj[instanceP].mt[mt_ix].nas_state==NAS_CX_DCH)&&(list[mt_ix].state == NAS_IDLE)){ - DEBUG ("\n\n"); - DEBUG (" MOBILE TERMINAL %d IS NOW IDLE.\n\n",mt_ix); - // TODO Send linkdown - } - //check if state has changed - MT reconnected FFS - if ((g_enb_ral_obj[instanceP].mt[mt_ix].nas_state==NAS_IDLE)&&(list[mt_ix].state == NAS_CX_DCH)){ - DEBUG ("\n\n"); - DEBUG (" MOBILE TERMINAL %d WAS IDLE AND IS NOW CONNECTED.\n\n",mt_ix); - } - //check if MT is completely connected - if ((g_enb_ral_obj[instanceP].mt[mt_ix].num_class - previous_num_class)&&(list[mt_ix].state == NAS_CX_DCH)){ - DEBUG ("\n\n"); - DEBUG (" MOBILE TERMINAL %d IS NOW COMPLETELY CONNECTED.\n\n",mt_ix); - // send linkup: new_ar will contain the address from the MT - new_ar.choice = MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_set(&(new_ar._union._3gpp_addr), (u_int8_t*)&(g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[0]), strlen(DEFAULT_ADDRESS_3GPP)); - - eRALlte_send_link_up_indication(&g_enb_ral_obj[instanceP].pending_req_transaction_id, &g_enb_ral_obj[instanceP].mt[mt_ix].ltid, NULL, &new_ar, NULL, NULL); - //eRALlte_send_link_up_indication(&g_enb_ral_obj[instanceP].pending_req_transaction_id, &g_enb_ral_obj[instanceP].mt[mt_ix].ltid, NULL, NULL, NULL, NULL); - // if RAL realtime and MEASURES are enabled, start the measuring process in RRC+Driver - #ifdef RAL_REALTIME - #ifdef ENABLE_MEDIEVAL_DEMO3 - RAL_process_NAS_message(IO_OBJ_MEAS, IO_CMD_ADD,0,0); - #endif - #endif - - } - //check enter sleep mode - if ((g_enb_ral_obj[instanceP].mt[mt_ix].nas_state==NAS_CX_DCH)&&(list[mt_ix].state == NAS_CX_RELEASING)){ - DEBUG ("\n\n"); - DEBUG (" MOBILE TERMINAL %d is entering sleep mode. Send LinkDown.\n\n",mt_ix); - // send linkdown: old_ar (represented by new_ar variable) will contain the address from the MT - transaction_id = MIH_C_get_new_transaction_id(); - reason_code = MIH_C_LINK_DOWN_REASON_EXPLICIT_DISCONNECT; - new_ar.choice = MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_set(&(new_ar._union._3gpp_addr), (u_int8_t*)&(g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[0]), strlen(DEFAULT_ADDRESS_3GPP)); - eRALlte_send_link_down_indication(&transaction_id, &g_enb_ral_obj[instanceP].mt[mt_ix].ltid, &new_ar, &reason_code); - } - // check leave sleep mode - if ((g_enb_ral_obj[instanceP].mt[mt_ix].nas_state==NAS_CX_RELEASING)&&(list[mt_ix].state == NAS_CX_DCH)){ - DEBUG ("\n\n"); - DEBUG (" MOBILE TERMINAL %d WAS IN SLEEP MODE AND IS NOW ACTIVATED.\n\n",mt_ix); - // send linkup: new_ar will contain the address from the MT - new_ar.choice = MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_set(&(new_ar._union._3gpp_addr), (u_int8_t*)&(g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[0]), strlen(DEFAULT_ADDRESS_3GPP)); - eRALlte_send_link_up_indication(&g_enb_ral_obj[instanceP].pending_req_transaction_id, &g_enb_ral_obj[instanceP].mt[mt_ix].ltid, NULL, &new_ar, NULL, NULL); - } - g_enb_ral_obj[instanceP].mt[mt_ix].nas_state = list[mt_ix].state; - }else{ - // MT unknown or different - if (list[mt_ix].state != NAS_IDLE){ - DEBUG ("\n\n"); - DEBUG (" NEW TERMINAL %d DETECTED.\n\n",mt_ix); - g_enb_ral_obj[instanceP].mt[mt_ix].ue_id = list[mt_ix].lcr; - g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[0]= list[mt_ix].iid6[0]; - g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[1]= list[mt_ix].iid6[1]; - g_enb_ral_obj[instanceP].mt[mt_ix].num_rbs = list[mt_ix].num_rb; - g_enb_ral_obj[instanceP].mt[mt_ix].num_class = list[mt_ix].nsclassifier; - // initialize ltid (MIH_C_LINK_TUPLE_ID_T) for that mobile - // first version - //g_enb_ral_obj[instanceP].mt[mt_ix].ltid.link_id.link_type = MIH_C_WIRELESS_UMTS; - //g_enb_ral_obj[instanceP].mt[mt_ix].ltid.link_id.link_addr.choice = MIH_C_CHOICE_3GPP_ADDR; - //MIH_C_3GPP_ADDR_set(&g_enb_ral_obj[instanceP].mt[mt_ix].ltid.link_id.link_addr._union._3gpp_addr, (u_int8_t*)&(g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[0]), strlen(DEFAULT_ADDRESS_3GPP)); - //g_enb_ral_obj[instanceP].mt[mt_ix].ltid.choice = MIH_C_LINK_TUPLE_ID_CHOICE_LINK_ADDR; - // SECOND Version - g_enb_ral_obj[instanceP].mt[mt_ix].ltid.link_id.link_type = MIH_C_WIRELESS_UMTS; - g_enb_ral_obj[instanceP].mt[mt_ix].ltid.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - g_enb_ral_obj[instanceP].mt[mt_ix].ltid.link_id.link_addr.choice = MIH_C_CHOICE_3GPP_3G_CELL_ID; - Bit_Buffer_t *plmn = new_BitBuffer_0(); - BitBuffer_wrap(plmn, (unsigned char*) g_enb_ral_obj[instanceP].plmn, DEFAULT_PLMN_SIZE); - MIH_C_PLMN_ID_decode(plmn, &g_enb_ral_obj[instanceP].mt[mt_ix].ltid.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id); - free_BitBuffer(plmn); - g_enb_ral_obj[instanceP].mt[mt_ix].ltid.link_id.link_addr._union._3gpp_3g_cell_id.cell_id = g_enb_ral_obj[instanceP].cell_id; - g_enb_ral_obj[instanceP].mt[mt_ix].ltid.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - - // check state of the UE connection - g_enb_ral_obj[instanceP].mt[mt_ix].nas_state = list[mt_ix].state; - if (g_enb_ral_obj[instanceP].mt[mt_ix].num_class>=2){ - g_enb_ral_obj[instanceP].mt[mt_ix].mt_state= RB_CONNECTED; - // send linkup - //ltid = &g_enb_ral_obj[instanceP].mt[mt_ix].ltid; - DEBUG (" MOBILE TERMINAL %d IS COMPLETELY CONNECTED.\n\n",mt_ix); - // new_ar will contain the address from the MT - new_ar.choice = MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_set(&(new_ar._union._3gpp_addr), (u_int8_t*)&(g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[0]), strlen(DEFAULT_ADDRESS_3GPP)); - - eRALlte_send_link_up_indication(&g_enb_ral_obj[instanceP].pending_req_transaction_id, &g_enb_ral_obj[instanceP].mt[mt_ix].ltid, NULL, &new_ar, NULL, NULL); - // if RAL realtime and MEASURES are enabled, start the measuring process in RRC+Driver - #ifdef RAL_REALTIME - #ifdef ENABLE_MEDIEVAL_DEMO3 - RAL_process_NAS_message(IO_OBJ_MEAS, IO_CMD_ADD,0,0); - #endif - #endif - } - // enter default rb - ch_ix = 0; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].rbId = RAL_DEFAULT_MC_RAB_ID+1; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].RadioQoSclass = 2; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].cnx_id = (RAL_MAX_RB_PER_UE*mt_ix)+ch_ix+1; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].dscpUL = 0; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].dscpDL = 0; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].nas_state = NAS_CX_DCH; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].status = RB_CONNECTED; - g_enb_ral_obj[instanceP].num_connected_mts++; - //RAL_printMobileData(mt_ix); - } - } // end if MT unknonwn - } // end for loop -} - -//--------------------------------------------------------------------------- -void RAL_verifyPendingRbStatus(void){ -//--------------------------------------------------------------------------- -// g_enb_ral_obj[instanceP].mcast.radio_channel.status = RB_CONNECTED; - int mt_ix, ch_ix; - MIH_C_LINK_TUPLE_ID_T* ltid; - //int is_unicast; - - mt_ix = g_enb_ral_obj[instanceP].pending_req_mt_ix; - ch_ix = g_enb_ral_obj[instanceP].pending_req_ch_ix; - - if ((g_enb_ral_obj[instanceP].pending_req_flag)%5==0){ - DEBUG("Pending Req Flag %d, Mobile %d, channel %d\n", g_enb_ral_obj[instanceP].pending_req_flag, mt_ix, ch_ix); - if (g_enb_ral_obj[instanceP].pending_req_multicast == RAL_TRUE){ - mt_ix =0; - ch_ix =1; - } - RAL_process_NAS_message(IO_OBJ_RB, IO_CMD_LIST,mt_ix,0); - if ((g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].status == RB_CONNECTED)||((g_enb_ral_obj[instanceP].pending_req_flag) > 100)){ - DEBUG("RAL_verifyPendingRbStatus -in- mt_ix %d - ch_ix %d \n", mt_ix, ch_ix ); - // send confirmation to upper layer - g_enb_ral_obj[instanceP].pending_req_status = MIH_C_STATUS_SUCCESS; - if ((g_enb_ral_obj[instanceP].pending_req_flag) > 100){ - g_enb_ral_obj[instanceP].pending_req_status = MIH_C_STATUS_REJECTED; - if (mt_ix == RAL_MAX_MT) - eRALlte_process_clean_channel(&(g_enb_ral_obj[instanceP].mcast.radio_channel)); - else - eRALlte_process_clean_channel(&(g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix])); - } - if (mt_ix == RAL_MAX_MT) - ltid = &g_enb_ral_obj[instanceP].mcast.ltid; - else - ltid = &g_enb_ral_obj[instanceP].mt[mt_ix].ltid; - - if (!g_enb_ral_obj[instanceP].pending_mt_flag) - // To be updated and completed - //aRALu_send_link_res_activate_cnf(); - eRALlte_send_link_up_indication(&g_enb_ral_obj[instanceP].pending_req_transaction_id, ltid, NULL, NULL, NULL, NULL); - else - g_enb_ral_obj[instanceP].pending_mt_flag = 0; - g_enb_ral_obj[instanceP].pending_req_flag = 0; - DEBUG("After response, Pending Req Flag = 0 , %d\n", g_enb_ral_obj[instanceP].pending_req_flag); - } - //DEBUG("RAL_verifyPendingRbStatus - 2- \n"); - } -} - -//--------------------------------------------------------------------------- -int RAL_process_NAS_message(int ioctl_obj, int ioctl_cmd, int mt_ix, int ch_ix){ -//--------------------------------------------------------------------------- - int err, rc; -// int mt_ix, ch_ix; - unsigned int cnxid; - -// DEBUG ("\n%d , %d,", mt_ix, ch_ix); - switch (ioctl_obj){ - case IO_OBJ_STATS: - { - DEBUG("Statistics requested -- FFS \n"); - } - break; - case IO_OBJ_CNX: - switch (ioctl_cmd){ - case IO_CMD_LIST: - { - // printf("Usage: gioctl cx list\n"); - uint8_t *msgrep; - uint8_t i; - struct nas_msg_cx_list_reply *list; - uint8_t lcr; - short int num_mts; - - gifr.type=NAS_MSG_CX_LIST_REQUEST; - //gifr.msg=(char *)malloc(NAS_LIST_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1); - memset (g_enb_ral_obj[instanceP].buffer,0,800); - gifr.msg= &(g_enb_ral_obj[instanceP].buffer[0]); - msgrep=(uint8_t *)(gifr.msg); - // - DEBUG("--\n"); - DEBUG("Connexion list requested\n"); - err=ioctl(fd, NASRG_IOCTL_RAL, &gifr); - if (err<0){ - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } - // Print result - DEBUG("Lcr\t\tCellId\tIID4\tIID6\t\t\tnum_rb\tnsclass\tState\n"); - list=(struct nas_msg_cx_list_reply *)(msgrep+1); - num_mts = msgrep[0]; - for(lcr=0; lcr<num_mts; ++lcr){ - DEBUG("%u\t\t%u\t%u\t", list[lcr].lcr, list[lcr].cellid, list[lcr].iid4); - for (i=0;i<8;++i) - DEBUG("%02x", *((uint8_t *)list[lcr].iid6+i)); - DEBUG("\t%u\t%u\t", list[lcr].num_rb, list[lcr].nsclassifier); - print_state(list[lcr].state); - } - if (init_flag){ - RAL_NASinitMTlist(msgrep, num_mts); - }else{ - RAL_NASupdatetMTlist(msgrep, num_mts); - } - rc = 0; - } - break; - default: - ERR ("RAL_process_NAS_message : invalid ioctl command %d\n",ioctl_cmd); - rc= -1; - } //end switch ioctl_cmd - break; - - case IO_OBJ_RB: - switch (ioctl_cmd){ - case IO_CMD_ADD: - { - // printf("Usage: gioctl rb add <lcr> <rab_id> <qos>\n"); - struct nas_msg_rb_establishment_request *msgreq; - struct nas_msg_rb_establishment_reply *msgrep; - struct ral_lte_channel *currChannel; - MIH_C_LINK_TUPLE_ID_T* ltid; - MIH_C_LINK_DN_REASON_T reason_code; - // - gifr.type=NAS_MSG_RB_ESTABLISHMENT_REQUEST; - memset (g_enb_ral_obj[instanceP].buffer,0,800); - gifr.msg= &(g_enb_ral_obj[instanceP].buffer[0]); - msgreq=(struct nas_msg_rb_establishment_request *)(gifr.msg); - msgrep=(struct nas_msg_rb_establishment_reply *)(gifr.msg); - // - if (mt_ix == RAL_MAX_MT){ - // multicast - currChannel = &(g_enb_ral_obj[instanceP].mcast.radio_channel); - msgreq->lcr = mt_ix; - memcpy ((char *)&(msgreq->mcast_group), (char *)&(g_enb_ral_obj[instanceP].mcast.mc_group_addr), 16); - }else{ - // unicast - currChannel = &(g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix]); - msgreq->lcr = g_enb_ral_obj[instanceP].mt[mt_ix].ue_id; - } - msgreq->cnxid = currChannel->cnx_id; - msgreq->rab_id = currChannel->rbId; - msgreq->qos = currChannel->RadioQoSclass; - msgreq->dscp_ul = currChannel->dscpUL; - msgreq->dscp_dl = currChannel->dscpDL; - msgreq->mcast_flag = currChannel->multicast; - cnxid = msgreq->cnxid; - currChannel->status = RB_DISCONNECTED; - // - DEBUG("Radio bearer establishment requested, cnxid %d\n", cnxid); - err=ioctl(fd, NASRG_IOCTL_RAL, &gifr); - if (err<0){ - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } - // check answer from NAS - msgrep->cnxid = cnxid; // Temp - hardcoded - - if ((msgrep->status<0)||(msgrep->cnxid!=cnxid)||(err<0)){ - ERR(" Radio bearer establishment failure: %d\n",msgrep->status); - currChannel->status = RB_DISCONNECTED; - rc = -1; - g_enb_ral_obj[instanceP].pending_req_status = MIH_C_STATUS_REJECTED; - if (g_enb_ral_obj[instanceP].pending_mt_flag){ - reason_code = MIH_C_LINK_DOWN_REASON_NO_RESOURCE; - if (mt_ix == RAL_MAX_MT) - ltid = &g_enb_ral_obj[instanceP].mcast.ltid; - else - ltid = &g_enb_ral_obj[instanceP].mt[mt_ix].ltid; - eRALlte_send_link_down_indication(&g_enb_ral_obj[instanceP].pending_req_transaction_id, ltid, NULL, &reason_code); - // aRALu_send_link_res_activate_cnf(); - } - if (mt_ix == RAL_MAX_MT) - eRALlte_process_clean_channel(&(g_enb_ral_obj[instanceP].mcast.radio_channel)); - else - eRALlte_process_clean_channel(&(g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix])); - }else{ - rc = 0; - g_enb_ral_obj[instanceP].pending_req_flag = 1; - g_enb_ral_obj[instanceP].pending_req_mt_ix = mt_ix; - g_enb_ral_obj[instanceP].pending_req_ch_ix = ch_ix; - g_enb_ral_obj[instanceP].pending_req_multicast = currChannel->multicast; - DEBUG("-1- pending_req_mt_ix %d, pending_req_ch_ix %d\n", g_enb_ral_obj[instanceP].pending_req_mt_ix, g_enb_ral_obj[instanceP].pending_req_ch_ix); - } - } - break; - - case IO_CMD_DEL: - { - // printf("Usage: gioctl rb del <lcr> <rab_id>\n"); - struct nas_msg_rb_release_request *msgreq; - struct nas_msg_rb_release_reply *msgrep; - struct ral_lte_channel *currChannel; - MIH_C_LINK_TUPLE_ID_T* ltid; - MIH_C_LINK_DN_REASON_T reason_code; - // - gifr.type=NAS_MSG_RB_RELEASE_REQUEST; - memset (g_enb_ral_obj[instanceP].buffer,0,800); - gifr.msg= &(g_enb_ral_obj[instanceP].buffer[0]); - msgreq=(struct nas_msg_rb_release_request *)(gifr.msg); - msgrep=(struct nas_msg_rb_release_reply *)(gifr.msg); - // - if (mt_ix == RAL_MAX_MT){ - currChannel = &(g_enb_ral_obj[instanceP].mcast.radio_channel); - msgreq->lcr = mt_ix; - }else{ - currChannel = &(g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix]); - msgreq->lcr = g_enb_ral_obj[instanceP].mt[mt_ix].ue_id; - } - msgreq->rab_id = currChannel->rbId; - msgreq->cnxid = currChannel->cnx_id; - msgreq->mcast_flag = currChannel->multicast; - cnxid = msgreq->cnxid; - // - DEBUG(" Radio Bearer release requested\n"); - err=ioctl(fd, NASRG_IOCTL_RAL, &gifr); - if (err<0){ - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } - // check answer from NAS - msgrep->cnxid = cnxid; // Temp - hardcoded - if ((msgrep->status<0)||(msgrep->cnxid!=cnxid)||(err<0)){ - ERR(" Radio bearer release failure: status %d\n", msgrep->status); - rc = -1; - g_enb_ral_obj[instanceP].pending_req_status = MIH_C_STATUS_REJECTED; - }else{ - g_enb_ral_obj[instanceP].pending_req_status = MIH_C_STATUS_SUCCESS; - } - if (g_enb_ral_obj[instanceP].pending_mt_flag){ - reason_code = MIH_C_LINK_DOWN_REASON_EXPLICIT_DISCONNECT; - if (mt_ix == RAL_MAX_MT) - ltid = &g_enb_ral_obj[instanceP].mcast.ltid; - else - ltid = &g_enb_ral_obj[instanceP].mt[mt_ix].ltid; - eRALlte_send_link_down_indication(&g_enb_ral_obj[instanceP].pending_req_transaction_id, ltid, NULL, &reason_code); - // aRALu_send_link_res_deactivate_cnf(); - } - - // mark resource as free again anyway - if (mt_ix == RAL_MAX_MT) - eRALlte_process_clean_channel(&(g_enb_ral_obj[instanceP].mcast.radio_channel)); - else - eRALlte_process_clean_channel(&(g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix])); - DEBUG("Channel released : UE %d, channel %d, cnx_id %d \n\n",mt_ix, ch_ix, cnxid); - } - break; - - - case IO_CMD_LIST: - { - // printf("Usage: gioctl rb list <lcr>\n"); - uint8_t *msgrep; - uint8_t rbi, i; - uint8_t num_rbs; - struct nas_msg_rb_list_reply *list; - struct nas_msg_rb_list_request *msgreq; - gifr.type=NAS_MSG_RB_LIST_REQUEST; - memset (g_enb_ral_obj[instanceP].buffer,0,800); - gifr.msg= &(g_enb_ral_obj[instanceP].buffer[0]); - msgreq=(struct nas_msg_rb_list_request *)(gifr.msg); - msgrep=(uint8_t *)(gifr.msg); - if (mt_ix < RAL_MAX_MT){ - msgreq->lcr = g_enb_ral_obj[instanceP].mt[mt_ix].ue_id; - }else{ - msgreq->lcr = 0; - mt_ix =0; //Temp - } - // - DEBUG(" Radio bearer list requested\n"); - err=ioctl(fd, NASRG_IOCTL_RAL, &gifr); - if (err<0){ - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } - num_rbs = msgrep[0]; - //RAL_print_buffer (msgrep, 50); - DEBUG("number of radio bearers %d \n", num_rbs); - DEBUG("rab_id\tcnxid\tSapi\t\tQoS\t\tState\n"); - list=(struct nas_msg_rb_list_reply *)(msgrep+1); - for(rbi=0; rbi<num_rbs; ++rbi){ - DEBUG("%u\t%u\t%u\t\t%u\t\t", list[rbi].rab_id,list[rbi].cnxid, list[rbi].sapi, list[rbi].qos); - print_state(list[rbi].state); - rc = 0; - // store channel status - for (i=0;i<num_rbs; i++){ - if (g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[i].cnx_id == list[rbi].cnxid){ - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[i].nas_state = list[rbi].state; - if (list[rbi].state == NAS_CX_DCH) - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[i].status = RB_CONNECTED; - } - } - if ((mt_ix==0)&&(i==num_rbs)){ - if (g_enb_ral_obj[instanceP].mcast.radio_channel.cnx_id == list[rbi].cnxid){ - g_enb_ral_obj[instanceP].mcast.radio_channel.nas_state = list[rbi].state; - if (list[rbi].state == NAS_CX_DCH){ - g_enb_ral_obj[instanceP].mcast.radio_channel.status = RB_CONNECTED; - g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[1].status = RB_CONNECTED; - } - } - } - } - DEBUG("List complete \n"); - } - break; - default: - ERR ("RAL_process_NAS_message : invalid ioctl command %d\n",ioctl_cmd); - rc= -1; - } //end switch ioctl_cmd - break; - case IO_OBJ_MEAS: - switch (ioctl_cmd){ - case IO_CMD_ADD: - { - struct nas_msg_enb_measure_trigger *msgreq; - struct nas_msg_enb_measure_trigger_reply *msgrep; - // - gifr.type=NAS_MSG_ENB_MEAS_TRIGGER; - memset (g_enb_ral_obj[instanceP].buffer,0,800); - gifr.msg= &(g_enb_ral_obj[instanceP].buffer[0]); - msgreq=(struct nas_msg_enb_measure_trigger *)(gifr.msg); - msgrep=(struct nas_msg_enb_measure_trigger_reply *)(gifr.msg); - // - msgreq->cell_id = g_enb_ral_obj[instanceP].cell_id; - // - DEBUG("eNB measures triggered, cell_id %d\n", msgreq->cell_id); - err=ioctl(fd, NASRG_IOCTL_RAL, &gifr); - if (err<0){ - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } - // check answer from NAS - if (msgrep->status != 0){ - ERR(" eNB measures trigger failure: %d\n",msgrep->status); - rc = -1; - }else{ - DEBUG(" eNB measures triggered successfully \n"); - rc = 0; - } - } - break; - case IO_CMD_LIST: - { - struct nas_msg_enb_measure_retrieve *msgrep; - int ix; - // - gifr.type=NAS_MSG_ENB_MEAS_RETRIEVE; - memset (g_enb_ral_obj[instanceP].buffer,0,800); - gifr.msg= &(g_enb_ral_obj[instanceP].buffer[0]); - msgrep=(struct nas_msg_enb_measure_retrieve *)(gifr.msg); - // - DEBUG("Retrieving measure from NAS\n"); - err=ioctl(fd, NASRG_IOCTL_RAL, &gifr); - if (err<0){ - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } - // Store the values received - g_enb_ral_obj[instanceP].num_UEs = msgrep->num_UEs; - for (ix=0; ix<g_enb_ral_obj[instanceP].num_UEs; ix++){ - g_enb_ral_obj[instanceP].rlcBufferOccupancy[ix] = msgrep->measures[ix].rlcBufferOccupancy; - g_enb_ral_obj[instanceP].scheduledPRB[ix] = msgrep->measures[ix].scheduledPRB; - g_enb_ral_obj[instanceP].totalDataVolume[ix] = msgrep->measures[ix].totalDataVolume; - } - g_enb_ral_obj[instanceP].totalNumPRBs = msgrep->totalNumPRBs; - #ifdef DEBUG_RAL_DETAILS - DEBUG("Measures received- cell %d, Number of UEs %d, Total number of PRBs %d\n", msgrep->cell_id, msgrep->num_UEs, msgrep->totalNumPRBs); - for (ix=0; ix<g_enb_ral_obj[instanceP].num_UEs; ix++) - DEBUG("UE%d : RLC Buffers %d, scheduledPRB %d, totalDataVolume %d\n", ix, msgrep->measures[ix].rlcBufferOccupancy, - msgrep->measures[ix].scheduledPRB, msgrep->measures[ix].totalDataVolume); - #endif - RAL_NAS_measures_analyze(); - } - break; - default: - ERR ("RAL_process_NAS_message : invalid ioctl command %d\n",ioctl_cmd); - rc= -1; - } //end switch ioctl_cmd - break; - - case IO_OBJ_MC: - switch (ioctl_cmd){ - case IO_CMD_ADD: - { - struct nas_msg_mt_mcast_join *msgreq; - struct nas_msg_mt_mcast_reply *msgrep; - struct ral_lte_channel *currChannel; - // - gifr.type=NAS_RG_MSG_MT_MCAST_JOIN; - memset (g_enb_ral_obj[instanceP].buffer,0,800); - gifr.msg= &(g_enb_ral_obj[instanceP].buffer[0]); - msgreq=(struct nas_msg_mt_mcast_join *)(gifr.msg); - msgrep=(struct nas_msg_mt_mcast_reply *)(gifr.msg); - // - currChannel = &(g_enb_ral_obj[instanceP].mcast.radio_channel); - msgreq->ue_id = mt_ix; - msgreq->rab_id = currChannel->rbId; - msgreq->cnxid = currChannel->cnx_id; - // - DEBUG("UE multicast join notification requested, ue_id %d\n", mt_ix); - err=ioctl(fd, NASRG_IOCTL_RAL, &gifr); - if (err<0){ - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } - // check answer from NAS - if ((msgrep->result<0)||(msgrep->ue_id!=mt_ix)||(err<0)){ - ERR(" UE multicast join notification failure: %d\n",msgrep->result); - g_enb_ral_obj[instanceP].pending_req_status = MIH_C_STATUS_REJECTED; - rc = -1; - }else{ - DEBUG(" ++ UE multicast join notification transmitted to MT \n"); - g_enb_ral_obj[instanceP].pending_req_status = MIH_C_STATUS_SUCCESS; - rc = 0; - } - // TODO aRALu_send_link_mc_join_cnf(); - } - break; - - case IO_CMD_DEL: - { - struct nas_msg_mt_mcast_leave *msgreq; - struct nas_msg_mt_mcast_reply *msgrep; - struct ral_lte_channel *currChannel; - // - gifr.type=NAS_RG_MSG_MT_MCAST_LEAVE; - memset (g_enb_ral_obj[instanceP].buffer,0,800); - gifr.msg= &(g_enb_ral_obj[instanceP].buffer[0]); - msgreq=(struct nas_msg_mt_mcast_leave *)(gifr.msg); - msgrep=(struct nas_msg_mt_mcast_reply *)(gifr.msg); - // - currChannel = &(g_enb_ral_obj[instanceP].mcast.radio_channel); - msgreq->ue_id = mt_ix; - msgreq->rab_id = currChannel->rbId; - msgreq->cnxid = currChannel->cnx_id; - // - DEBUG("UE multicast leave notification requested, ue_id %d\n", mt_ix); - err=ioctl(fd, NASRG_IOCTL_RAL, &gifr); - if (err<0){ - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } - // check answer from NAS - if ((msgrep->result<0)||(msgrep->ue_id!=mt_ix)||(err<0)){ - ERR(" UE multicast leave notification failure: %d\n",msgrep->result); - g_enb_ral_obj[instanceP].pending_req_status = MIH_C_STATUS_REJECTED; - rc = -1; - }else{ - DEBUG(" ++ UE multicast leave notification transmitted to MT \n" ); - g_enb_ral_obj[instanceP].pending_req_status = MIH_C_STATUS_SUCCESS; - rc = 0; - } - // TODO aRALu_send_link_mc_leave_cnf(); - } - break; - default: - ERR ("RAL_process_NAS_message : invalid ioctl command %d\n",ioctl_cmd); - rc= -1; - } //end switch ioctl_cmd - break; - default: - ERR ("RAL_process_NAS_message : invalid ioctl object %d\n",ioctl_obj); - rc= -1; - } //end switch ioctl_obj - //rc=0; - return rc; -} -*/ - - diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_main.c b/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_main.c deleted file mode 100755 index df13c030f3..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_main.c +++ /dev/null @@ -1,340 +0,0 @@ -/***************************************************************************** - * Eurecom OpenAirInterface 3 - * Copyright(c) 2012 Eurecom - * - * Source lteRALenb_main.c - * Version 0.1 - * Date 01/17/2014 - * Product MIH RAL LTE - * Subsystem RAL main process running at the network side - * Authors Michelle Wetterwald, Lionel Gauthier, Frederic Maurel - * Description Implements the Radio Access Link process that interface the - * Media Independent Handover (MIH) Function to the LTE specific - * L2 media-dependent access layer. - * - * The MIH Function provides network information to upper layers - * and requests actions from lower layers to optimize handovers - * between heterogeneous networks. - *****************************************************************************/ -#define LTE_RAL_ENB -#define LTE_RAL_ENB_MAIN_C -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <sys/epoll.h> -#include <sys/select.h> -#include <net/if.h> -#include <getopt.h> -#include <stdlib.h> -#include <time.h> -//----------------------------------------------------------------------------- -#include "assertions.h" -#include "lteRALenb.h" -#include "intertask_interface.h" -#include "OCG.h" -//----------------------------------------------------------------------------- - - - -/****************************************************************************/ -/******************* G L O B A L D E F I N I T I O N S *****************/ -/****************************************************************************/ -extern OAI_Emulation oai_emulation; - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -/**************************************************************************** - ** Name: get_IPv6_addr() ** - ** Description: Gets the IPv6 address of the specified network interface. ** - ** Inputs: if_name Interface name ** - ***************************************************************************/ -void eRAL_get_IPv6_addr(const char* if_name) -{ - //----------------------------------------------------------------------------- -#define IPV6_ADDR_LINKLOCAL 0x0020U - - FILE *f; - char devname[20]; - int plen, scope, dad_status, if_idx; - char addr6p[8][5]; - int found = 0; - char my_addr[16]; - char temp_addr[32]; - int i, j; - - LOG_D(RAL_ENB, " %s : network interface %s\n", __FUNCTION__, if_name); - - if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) { - while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], - addr6p[4], addr6p[5], addr6p[6], addr6p[7], - &if_idx, &plen, &scope, &dad_status, devname) != EOF) { - - if (!strcmp(devname, if_name)) { - found = 1; - - // retrieve numerical value - if ((scope == 0) || (scope == IPV6_ADDR_LINKLOCAL)) { - LOG_D(RAL_ENB, " adresse %s:%s:%s:%s:%s:%s:%s:%s", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], - addr6p[4], addr6p[5], addr6p[6], addr6p[7]); - LOG_D(RAL_ENB, " Scope:"); - - switch (scope) { - case 0: - LOG_D(RAL_ENB, " Global\n"); - break; - - case IPV6_ADDR_LINKLOCAL: - LOG_D(RAL_ENB, " Link\n"); - break; - - default: - LOG_D(RAL_ENB, " Unknown\n"); - break; - } - - LOG_D(RAL_ENB, " Numerical value: "); - - for (i = 0; i < 8; i++) { - for (j = 0; j < 4; j++) { - addr6p[i][j]= toupper(addr6p[i][j]); - - if ((addr6p[i][j] >= 'A') && (addr6p[i][j] <= 'F')) { - temp_addr[(4*i)+j] =(unsigned short int)(addr6p[i][j]-'A')+10; - } else if ((addr6p[i][j] >= '0') && (addr6p[i][j] <= '9')) { - temp_addr[(4*i)+j] =(unsigned short int)(addr6p[i][j]-'0'); - } - } - - my_addr[2*i] = (16*temp_addr[(4*i)])+temp_addr[(4*i)+1]; - my_addr[(2*i)+1] = (16*temp_addr[(4*i)+2])+temp_addr[(4*i)+3]; - - } - - for (i = 0; i < 16; i++) { - LOG_D(RAL_ENB, "-%hhx-",my_addr[i]); - } - - LOG_D(RAL_ENB, "\n"); - } - } - } - - fclose(f); - - if (!found) { - LOG_E(RAL_ENB, " %s : interface %s not found\n\n", __FUNCTION__, if_name); - } - } -} - -void eRAL_init_default_values(void) -{ - g_conf_enb_ral_listening_port = ENB_DEFAULT_LOCAL_PORT_RAL; - g_conf_enb_ral_ip_address = ENB_DEFAULT_IP_ADDRESS_RAL; - g_conf_enb_ral_link_id = ENB_DEFAULT_LINK_ID_RAL; - g_conf_enb_ral_link_address = ENB_DEFAULT_LINK_ADDRESS_RAL; - g_conf_enb_mihf_remote_port = ENB_DEFAULT_REMOTE_PORT_MIHF; - g_conf_enb_mihf_ip_address = ENB_DEFAULT_IP_ADDRESS_MIHF; - g_conf_enb_mihf_id = ENB_DEFAULT_MIHF_ID; -} - -/**************************************************************************** - ** Name: eRAL_initialize() ** - ** ** - ** Description: Performs overall RAL LTE initialisations: ** - ** ** - ** Inputs: None ** - ** ** - ***************************************************************************/ -int eRAL_initialize(void) -{ - //----------------------------------------------------------------------------- - ral_enb_instance_t instance = 0; - unsigned int mod_id = 0; - char *char_tmp = NULL; - - MIH_C_init(); - - srand(time(NULL)); - - memset(g_enb_ral_obj, 0, sizeof(lte_ral_enb_object_t)*MAX_MODULES); - - g_enb_ral_fd2instance = hashtable_create (32, NULL, hash_free_int_func); - - for (mod_id = 0; mod_id < oai_emulation.info.nb_enb_local; mod_id++) { - char_tmp = calloc(1, strlen(g_conf_enb_ral_listening_port) + 3); // 2 digits + \0 ->99 instances - instance = mod_id; - - sprintf(char_tmp,"%d", atoi(g_conf_enb_ral_listening_port) + mod_id); - g_enb_ral_obj[mod_id].ral_listening_port = char_tmp; - - g_enb_ral_obj[mod_id].ral_ip_address = strdup(g_conf_enb_ral_ip_address); - g_enb_ral_obj[mod_id].ral_link_address = strdup(g_conf_enb_ral_link_address); - - char_tmp = calloc(1, strlen(g_conf_enb_mihf_remote_port) + 3); // 2 digits + \0 ->99 instances - sprintf(char_tmp, "%d", atoi(g_conf_enb_mihf_remote_port) + instance); - g_enb_ral_obj[mod_id].mihf_remote_port = char_tmp; - - g_enb_ral_obj[mod_id].mihf_ip_address = strdup(g_conf_enb_mihf_ip_address); - - char_tmp = calloc(1, strlen(g_conf_enb_mihf_id) + 3); // 2 digits + \0 ->99 instances - sprintf(char_tmp, "%s%02d",g_conf_enb_mihf_id, instance); - g_enb_ral_obj[mod_id].mihf_id = char_tmp; - - char_tmp = calloc(1, strlen(g_conf_enb_ral_link_id) + 3); // 2 digits + \0 ->99 instances - sprintf(char_tmp, "%s%02d",g_conf_enb_ral_link_id, mod_id); - g_enb_ral_obj[mod_id].link_id = char_tmp; - char_tmp = NULL; - - // excluded MIH_C_LINK_AC_TYPE_NONE - // excluded MIH_C_LINK_AC_TYPE_LINK_DISCONNECT - // excluded MIH_C_LINK_AC_TYPE_LINK_LOW_POWER - // excluded MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN - // excluded MIH_C_LINK_AC_TYPE_LINK_POWER_UP - g_enb_ral_obj[mod_id].mih_supported_link_action_list = (1 << MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR) | - (1 << MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES) | - (1 << MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES)| - (1 << MIH_C_LINK_AC_TYPE_LINK_POWER_UP)| - (1 << MIH_C_LINK_AC_TYPE_LINK_DISCONNECT)| - (1 << MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN); - // excluded MIH_C_BIT_LINK_DETECTED - // excluded MIH_C_BIT_LINK_GOING_DOWN - // excluded MIH_C_BIT_LINK_HANDOVER_IMMINENT - // excluded MIH_C_BIT_LINK_HANDOVER_COMPLETE - // excluded MIH_C_BIT_LINK_PDU_TRANSMIT_STATUS - g_enb_ral_obj[mod_id].mih_supported_link_event_list = MIH_C_BIT_LINK_UP | MIH_C_BIT_LINK_DOWN | MIH_C_BIT_LINK_PARAMETERS_REPORT; - // excluded MIH_C_BIT_LINK_GET_PARAMETERS - // excluded MIH_C_BIT_LINK_CONFIGURE_THRESHOLDS - g_enb_ral_obj[mod_id].mih_supported_link_command_list = MIH_C_BIT_LINK_EVENT_SUBSCRIBE | MIH_C_BIT_LINK_CONFIGURE_THRESHOLDS | MIH_C_BIT_LINK_ACTION | - MIH_C_BIT_LINK_EVENT_UNSUBSCRIBE | - MIH_C_BIT_LINK_ACTION; - - g_enb_ral_obj[mod_id].link_mihcap_flag = MIH_C_BIT_EVENT_SERVICE_SUPPORTED | MIH_C_BIT_COMMAND_SERVICE_SUPPORTED | MIH_C_BIT_INFORMATION_SERVICE_SUPPORTED; - - g_enb_ral_obj[mod_id].net_caps = MIH_C_BIT_NET_CAPS_QOS_CLASS5 | MIH_C_BIT_NET_CAPS_INTERNET_ACCESS | MIH_C_BIT_NET_CAPS_MIH_CAPABILITY; - - - g_enb_ral_obj[mod_id].transaction_id = (MIH_C_TRANSACTION_ID_T)rand(); - - - g_enb_ral_obj[mod_id].ue_htbl = hashtable_create(32, NULL, NULL); - - LOG_D(RAL_ENB, " Connect to the MIH-F for module id instance %d...\n", mod_id, instance); - g_enb_ral_obj[mod_id].mih_sock_desc = -1; - AssertFatal(eRAL_mihf_connect(instance) >= 0, " %s : Could not connect to MIH-F...\n", __FUNCTION__); - itti_subscribe_event_fd(TASK_RAL_ENB, g_enb_ral_obj[mod_id].mih_sock_desc); - hashtable_insert(g_enb_ral_fd2instance, g_enb_ral_obj[mod_id].mih_sock_desc, (void*)instance); - - eRAL_send_link_register_indication(instance, &g_enb_ral_obj[mod_id].transaction_id); - g_enb_ral_obj[mod_id].transaction_id += 1; - } - - return 0; -} - -void eRAL_process_file_descriptors(struct epoll_event *events, int nb_events) -{ - int i; - ral_enb_instance_t instance; - hashtable_rc_t rc; - - if (events == NULL) { - return; - } - - for (i = 0; i < nb_events; i++) { - rc = hashtable_get(g_enb_ral_fd2instance, events[i].data.fd, (void**)&instance); - - if (rc == HASH_TABLE_OK) { - eRAL_mih_link_process_message(instance); - } - } -} - -void* eRAL_task(void *args_p) -{ - int nb_events; - struct epoll_event *events; - MessageDef *msg_p = NULL; - const char *msg_name = NULL; - instance_t instance = 0; - - - eRAL_initialize(); - itti_mark_task_ready (TASK_RAL_ENB); - - while(1) { - // Wait for a message - itti_receive_msg (TASK_RAL_ENB, &msg_p); - - if (msg_p != NULL) { - - msg_name = ITTI_MSG_NAME (msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); - - switch (ITTI_MSG_ID(msg_p)) { - case TERMINATE_MESSAGE: - // TO DO - itti_exit_task (); - break; - - case TIMER_HAS_EXPIRED: - LOG_D(RAL_ENB, "Received %s\n", msg_name); - break; - - case RRC_RAL_SYSTEM_CONFIGURATION_IND: - LOG_D(RAL_ENB, "Received %s\n", msg_name); - eRAL_rx_rrc_ral_system_configuration_indication(instance, msg_p); - break; - - case RRC_RAL_CONNECTION_ESTABLISHMENT_IND: - LOG_D(RAL_ENB, "Received %s\n", msg_name); - eRAL_rx_rrc_ral_connection_establishment_indication(instance, msg_p); - break; - - case RRC_RAL_CONNECTION_REESTABLISHMENT_IND: - LOG_D(RAL_ENB, "Received %s\n", msg_name); - eRAL_rx_rrc_ral_connection_reestablishment_indication(instance, msg_p); - break; - - case RRC_RAL_CONNECTION_RECONFIGURATION_IND: - LOG_D(RAL_ENB, "Received %s\n", msg_name); - eRAL_rx_rrc_ral_connection_reconfiguration_indication(instance, msg_p); - break; - - case RRC_RAL_MEASUREMENT_REPORT_IND: - LOG_D(RAL_ENB, "Received %s\n", msg_name); - eRAL_rx_rrc_ral_measurement_report_indication(instance, msg_p); - break; - - case RRC_RAL_CONNECTION_RELEASE_IND: - LOG_D(RAL_ENB, "Received %s\n", msg_name); - eRAL_rx_rrc_ral_connection_release_indication(instance, msg_p); - break; - - case RRC_RAL_CONFIGURE_THRESHOLD_CONF: - LOG_D(RAL_ENB, "Received %s\n", msg_name); - eRAL_rx_rrc_ral_configure_threshold_conf(instance, msg_p); - break; - - default: - LOG_E(RAL_ENB, "Received unexpected message %s\n", msg_name); - break; - } - - itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - msg_p = NULL; - } - - nb_events = itti_get_events(TASK_RAL_ENB, &events); - - /* Now handle notifications for other sockets */ - if (nb_events > 0) { - eRAL_process_file_descriptors(events, nb_events); - } - } -} - diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_mih_msg.c b/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_mih_msg.c deleted file mode 100755 index 4791dc7c8c..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_mih_msg.c +++ /dev/null @@ -1,1447 +0,0 @@ -/*************************************************************************** - lteRALenb_mih_msg.c - description - *************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 1999 - 2013 Eurecom - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information - Openair Admin: openair_admin@eurecom.fr - Openair Tech : openair_tech@eurecom.fr - Forums : http://forums.eurecom.fsr/openairinterface - Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France - *******************************************************************************/ -/*! \file lteRALenb_mih_msg.c - * \brief Interface for MIH primitives in LTE-RAL-ENB - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#define LTE_RAL_ENB -#define LTE_RAL_ENB_MIH_MSG_C -#include "lteRALenb.h" - -/****************************************************************************/ -/******************* G L O C A L D E F I N I T I O N S *****************/ -/****************************************************************************/ - -#define MSG_CODEC_RECV_BUFFER_SIZE 16400 -#define MSG_CODEC_SEND_BUFFER_SIZE 16400 - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -static u_int8_t g_msg_codec_recv_buffer[MSG_CODEC_RECV_BUFFER_SIZE] = {}; -static u_int8_t g_msg_codec_send_buffer[MSG_CODEC_SEND_BUFFER_SIZE] = {}; - -static char g_msg_print_buffer[8192] = {}; -static char g_msg_codec_print_buffer[8192] = {}; - - -//----------------------------------------------------------------------------- -void eRAL_MIH_C_3GPP_ADDR_load_3gpp_str_address(ral_enb_instance_t instanceP, MIH_C_3GPP_ADDR_T* _3gpp_addr_pP, u_int8_t* str_pP) -//----------------------------------------------------------------------------- -{ - int i, l; - u_int8_t val_temp; - unsigned char address_3gpp[32]; - unsigned char buf[3]; - u_int8_t _3gpp_byte_address[8]; - module_id_t mod_id = instanceP; - - strcpy((char *)address_3gpp, (char *)str_pP); - - for(l=0; l<8; l++) { - i=l*2; - buf[0]= address_3gpp[i]; - buf[1]= address_3gpp[i+1]; - buf[2]= '\0'; - //sscanf((const char *)buf,"%02x", &val_temp); - sscanf((const char *)buf,"%hhx", &val_temp); - _3gpp_byte_address[l] = val_temp; - } - - _3gpp_byte_address[7] += mod_id; - MIH_C_3GPP_ADDR_set(_3gpp_addr_pP, _3gpp_byte_address, 8); -} - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ -/* - * ------------------------------------------------------------------------- - * Functions used to send MIH link service management messages - * ------------------------------------------------------------------------- - */ - -/**************************************************************************** - ** Name: eRAL_send_link_register_indication() ** - ** Description: Sends a Link_Register.indication message to the MIHF. ** - ** This message is ODTONE specific and not defined by the 802.21 ** - ** standard. It allows the Link SAP to send informations to the MIHF ** - ** about which technology it supports and which interface it manages. ** - ** Upon receiving this message the MIHF executes its Link SAPs ** - ** discovery procedure in order to get the full link capabilities. ** - ** Inputs: tid_pP Transaction identifier ** - ** Others: g_enb_ral_obj[instanceP].link_id, g_enb_ral_obj[instanceP].mihf_id, ralpriv ** - ** Outputs: None ** - ** Others: g_msg_codec_send_buffer ** - ***************************************************************************/ -void eRAL_send_link_register_indication(ral_enb_instance_t instanceP, MIH_C_TRANSACTION_ID_T *tid_pP) -{ - MIH_C_Message_Link_Register_indication_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP; - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_REGISTER_INDICATION\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Register_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)6; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[mod_id].link_id, strlen(g_enb_ral_obj[mod_id].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[mod_id].mihf_id, strlen(g_enb_ral_obj[mod_id].mihf_id)); - - message.primitive.Link_Id.link_type = MIH_C_WIRELESS_LTE; //MIH_C_WIRELESS_UMTS; -#ifdef USE_3GPP_ADDR_AS_LINK_ADDR - message.primitive.Link_Id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - eRAL_MIH_C_3GPP_ADDR_load_3gpp_str_address(mod_id, &message.primitive.Link_Id.link_addr._union._3gpp_addr, (u_int8_t*)ENB_DEFAULT_3GPP_ADDRESS); -#else - message.primitive.Link_Id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_3G_CELL_ID; - memcpy(message.primitive.Link_Id.link_addr._union._3gpp_3g_cell_id.plmn_id.val, &g_enb_ral_obj[mod_id].plmn_id, 3); - message.primitive.Link_Id.link_addr._union._3gpp_3g_cell_id.cell_id = g_enb_ral_obj[mod_id].cell_id; - //Bit_Buffer_t *plmn = new_BitBuffer_0(); - //BitBuffer_wrap(plmn, (unsigned char*) &g_enb_ral_obj[instanceP].plmn_id, DEFAULT_PLMN_SIZE); - //MIH_C_PLMN_ID_decode(plmn, &message.primitive.Link_Id.link_addr._union._3gpp_3g_cell_id.plmn_id); - //message.primitive.Link_Id.link_addr._union._3gpp_3g_cell_id.cell_id = g_enb_ral_obj[instanceP].cell_id; - //free_BitBuffer(plmn); -#endif - - message_total_length = MIH_C_Link_Message_Encode_Link_Register_indication(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Register.indication\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Register.indication\n"); - } - - free_BitBuffer(bb_p); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_send_capability_discover_confirm() ** - ** ** - ** Description: Sends capability discover service management response to ** - ** the MIH-F. ** - ** ** - ** Inputs: tid_pP Transaction identifier ** - ** statusP: Status of operation ** - ** levt_listP: List of events supported by the link layer ** - ** lcmd_listP: List of commands supported by the link ** - ** layer ** - ** Others: g_enb_ral_obj[instanceP].link_id, g_enb_ral_obj[instanceP].mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRAL_send_capability_discover_confirm(ral_enb_instance_t instanceP, MIH_C_TRANSACTION_ID_T *tid_pP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *link_evt_listP, - MIH_C_LINK_CMD_LIST_T *link_cmd_listP) -{ - MIH_C_Message_Link_Capability_Discover_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_CONFIRM\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Capability_Discover_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[instanceP].link_id, strlen(g_enb_ral_obj[instanceP].link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[instanceP].mihf_id, strlen(g_enb_ral_obj[instanceP].mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.SupportedLinkEventList = link_evt_listP; - message.primitive.SupportedLinkCommandList = link_cmd_listP; - - message_total_length = MIH_C_Link_Message_Encode_Capability_Discover_confirm(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Capability_Discover.confirm\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Capability_Discover.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_send_event_subscribe_confirm() ** - ** ** - ** Description: Sends a Link_Event_Subscribe.confirm message to the MIHF. ** - ** ** - ** This primitive is generated in response to a Link_Event_ ** - ** Subscribe.request. ** - ** ** - ** Inputs: tid_pP Transaction identifier ** - ** statusP: Status of operation ** - ** levt_listP: List of successfully subscribed link events** - ** Others: g_enb_ral_obj[instanceP].link_id, g_enb_ral_obj[instanceP].mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRAL_send_event_subscribe_confirm(ral_enb_instance_t instanceP, MIH_C_TRANSACTION_ID_T *tid_pP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *levt_listP) -{ - MIH_C_Message_Link_Event_Subscribe_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_CONFIRM\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Event_Subscribe_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)4; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[instanceP].link_id, strlen(g_enb_ral_obj[instanceP].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[instanceP].mihf_id, strlen(g_enb_ral_obj[instanceP].mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.ResponseLinkEventList = levt_listP; - - message_total_length = MIH_C_Link_Message_Encode_Event_Subscribe_confirm(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Event_Subscribe.confirm\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Event_Subscribe.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_send_event_unsubscribe_confirm() ** - ** ** - ** Description: Sends a Link_Event_Unsubscribe.confirm message to the ** - ** MIHF. ** - ** ** - ** This primitive is generated in response to a Link_Event_ ** - ** Unsubscribe.request. ** - ** ** - ** Inputs: tid_pP Transaction identifier ** - ** statusP: Status of operation ** - ** levt_listP: List of successfully subscribed link events** - ** Others: g_enb_ral_obj[instanceP].link_id, g_enb_ral_obj[instanceP].mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRAL_send_event_unsubscribe_confirm(ral_enb_instance_t instanceP, MIH_C_TRANSACTION_ID_T *tid_pP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *levt_listP) -{ - MIH_C_Message_Link_Event_Unsubscribe_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_CONFIRM\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Event_Unsubscribe_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)5; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[instanceP].link_id, strlen(g_enb_ral_obj[instanceP].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[instanceP].mihf_id, strlen(g_enb_ral_obj[instanceP].mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.ResponseLinkEventList = levt_listP; - - message_total_length = MIH_C_Link_Message_Encode_Event_Unsubscribe_confirm(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Event_Unsubscribe.confirm\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Event_Unsubscribe.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -/* - * ------------------------------------------------------------------------- - * Functions used to send MIH link event messages - * ------------------------------------------------------------------------- - */ - -/**************************************************************************** - ** ** - ** Name: eRAL_send_link_detected_indication() ** - ** ** - ** Description: Sends a Link_Detected.indication message to the MIHF. ** - ** ** - ** The Link Detected event is generated on the MN when the ** - ** first PoA of an access network is detected. This event is ** - ** not generated when subsequent PoAs of the same access ** - ** network are discovered during the active connection on ** - ** that link. ** - ** ** - ** Inputs: tid_pP Transaction identifier ** - ** linfoP: Information of the detected link ** - ** Others: g_enb_ral_obj[instanceP].link_id, g_enb_ral_obj[instanceP].mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRAL_send_link_detected_indication(ral_enb_instance_t instanceP, MIH_C_TRANSACTION_ID_T *tid_pP, MIH_C_LINK_DET_INFO_T *linfoP) -{ - MIH_C_Message_Link_Detected_indication_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - - if (!(g_enb_ral_obj[instanceP].mih_supported_link_event_list & MIH_C_BIT_LINK_DETECTED)) { - return; - } - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_DETECTED_INDICATION\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Detected_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[instanceP].link_id, strlen(g_enb_ral_obj[instanceP].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[instanceP].mihf_id, strlen(g_enb_ral_obj[instanceP].mihf_id)); - - memcpy(&message.primitive.LinkDetectedInfo, linfoP, - sizeof(MIH_C_LINK_DET_INFO_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Detected_indication(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Detected.indication\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Detected.indication\n"); - } - - free_BitBuffer(bb_p); -} - -/**************************************************************************** - ** Name: eRAL_send_link_up_indication() ** - ** Description: Sends a Link_Up.indication message to the MIHF. ** - ** ** - ** This notification is generated when a layer 2 connection is ** - ** established for the specified link interface. ** - ** Inputs: tid_pP Transaction identifier ** - ** lid_pP: Link identifier ** - ** old_ar_pP: Old access router link address ** - ** new_arP: New access router link address ** - ** flagP: Indicates whether the MN needs to change IP Address ** - ** in the new PoA ** - ** mobil_mngtP: Indicates the type of Mobility Management ** - ** Protocol supported by the new PoA ** - ***************************************************************************/ -void eRAL_send_link_up_indication(ral_enb_instance_t instanceP, MIH_C_TRANSACTION_ID_T *tid_pP, - MIH_C_LINK_TUPLE_ID_T *lid_pP, - MIH_C_LINK_ADDR_T *old_ar_pP, - MIH_C_LINK_ADDR_T *new_arP, - MIH_C_IP_RENEWAL_FLAG_T *flagP, - MIH_C_IP_MOB_MGMT_T *mobil_mngtP) -{ - MIH_C_Message_Link_Up_indication_t message; - Bit_Buffer_t *bb_p = NULL; - int message_total_length; - module_id_t mod_id = instanceP; - - if (!(g_enb_ral_obj[mod_id].mih_supported_link_event_list & MIH_C_BIT_LINK_UP)) { - return; - } - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_UP_INDICATION\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Up_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)2; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[mod_id].link_id, strlen(g_enb_ral_obj[instanceP].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[mod_id].mihf_id, strlen(g_enb_ral_obj[instanceP].mihf_id)); - - memcpy(&message.primitive.LinkIdentifier, lid_pP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - - message.primitive.OldAccessRouter = old_ar_pP; - message.primitive.NewAccessRouter = new_arP; - message.primitive.IPRenewalFlag = flagP; - message.primitive.MobilityManagementSupport = mobil_mngtP; - - message_total_length = MIH_C_Link_Message_Encode_Link_Up_indication(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Up.indication\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Up.indication\n"); - } - - free_BitBuffer(bb_p); -} - -/**************************************************************************** - ** Name: eRAL_send_link_down_indication() ** - ** Description: Sends a Link_Down.indication message to the MIHF. ** - ** ** - ** This notification is generated when layer 2 connectivity is lost. ** - ** Layer 2 connectivity is lost explicitly in cases where the MN ** - ** initiates detach type procedures. In other cases, the MN can infer ** - ** loss of link connectivity due to successive time-outs for ** - ** acknowledgements of retransmitted packets along with loss of ** - ** reception of broadcast frames. ** - ** Inputs: tid_pP Transaction identifier ** - ** lid_pP: Link identifier ** - ** old_ar_pP: Old access router link address ** - ** reason_codeP: Reason why the link went down ** - ***************************************************************************/ -void eRAL_send_link_down_indication(ral_enb_instance_t instanceP, MIH_C_TRANSACTION_ID_T *tid_pP, - MIH_C_LINK_TUPLE_ID_T *lid_pP, - MIH_C_LINK_ADDR_T *old_ar_pP, - MIH_C_LINK_DN_REASON_T *reason_codeP) -{ - MIH_C_Message_Link_Down_indication_t message; - Bit_Buffer_t *bb_p = NULL; - int message_total_length; - - if (!(g_enb_ral_obj[instanceP].mih_supported_link_event_list & MIH_C_BIT_LINK_DOWN)) { - return; - } - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_DOWN_INDICATION\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Going_Down_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)3; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[instanceP].link_id, strlen(g_enb_ral_obj[instanceP].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[instanceP].mihf_id, strlen(g_enb_ral_obj[instanceP].mihf_id)); - - memcpy(&message.primitive.LinkIdentifier, lid_pP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - message.primitive.OldAccessRouter = old_ar_pP; - memcpy(&message.primitive.ReasonCode, reason_codeP, sizeof(MIH_C_LINK_DN_REASON_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Down_indication(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Down.indication\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Down.indication\n"); - } - - free_BitBuffer(bb_p); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_send_link_parameters_report_indication() ** - ** ** - ** Description: Sends a Link_Parameters_Report.indication message to the ** - ** MIHF. ** - ** ** - ** For each specified parameter, this notification is gene- ** - ** rated either at a predefined regular interval determined ** - ** by a user configurable timer or when it crosses a confi- ** - ** gured threshold. ** - ** ** - ** Inputs: tid_pP Transaction identifier ** - ** lid_pP: Link identifier ** - ** lparam_listP: List of link parameter reports ** - ** Others: g_enb_ral_obj[instanceP].link_id, g_enb_ral_obj[instanceP].mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRAL_send_link_parameters_report_indication(ral_enb_instance_t instanceP, MIH_C_TRANSACTION_ID_T *tid_pP, - MIH_C_LINK_TUPLE_ID_T *lid_pP, - MIH_C_LINK_PARAM_RPT_LIST_T *lparam_listP) -{ - MIH_C_Message_Link_Parameters_Report_indication_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - - if (!(g_enb_ral_obj[instanceP].mih_supported_link_event_list & MIH_C_BIT_LINK_PARAMETERS_REPORT)) { - return; - } - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_PARAMETERS_REPORT_INDICATION\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Parameters_Report_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)5; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[instanceP].link_id, strlen(g_enb_ral_obj[instanceP].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[instanceP].mihf_id, strlen(g_enb_ral_obj[instanceP].mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, lid_pP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - memcpy(&message.primitive.LinkParametersReportList_list, lparam_listP, sizeof(MIH_C_LINK_PARAM_RPT_LIST_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Parameters_Report_indication(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Parameters_Report.indication\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Parameters_Report.indication\n"); - } - - free_BitBuffer(bb_p); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_send_link_going_down_indication() ** - ** ** - ** Description: Sends a Link_Going_Down.indication message to the MIHF. ** - ** ** - ** A Link_Going_Down event implies that a Link_Down is immi- ** - ** nent within a certain time interval. If Link_Down is NOT ** - ** received within specified time interval then actions due ** - ** to previous Link_Going_Down are ignored. ** - ** ** - ** Inputs: tid_pP Transaction identifier ** - ** lid_pP: Link identifier ** - ** timeP: The time interval (ms) at which the link ** - ** is expected to go down (0 if unknown) ** - ** lreasonP: Reason why the link is going to be down ** - ** Others: g_enb_ral_obj[instanceP].link_id, g_enb_ral_obj[instanceP].mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRAL_send_link_going_down_indication(ral_enb_instance_t instanceP, MIH_C_TRANSACTION_ID_T *tid_pP, - MIH_C_LINK_TUPLE_ID_T *lid_pP, - MIH_C_UNSIGNED_INT2_T *timeP, - MIH_C_LINK_GD_REASON_T *lreasonP) -{ - MIH_C_Message_Link_Going_Down_indication_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - - if (!(g_enb_ral_obj[instanceP].mih_supported_link_event_list & MIH_C_BIT_LINK_GOING_DOWN)) { - return; - } - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_GOING_DOWN_INDICATION\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Going_Down_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)6; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[instanceP].link_id, strlen(g_enb_ral_obj[instanceP].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[instanceP].mihf_id, strlen(g_enb_ral_obj[instanceP].mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, lid_pP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - message.primitive.TimeInterval = *timeP; - memcpy(&message.primitive.LinkGoingDownReason, lreasonP, - sizeof(MIH_C_LINK_GD_REASON_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Going_Down_indication(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Going_Down.indication\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Going_Down.indication\n"); - } - - free_BitBuffer(bb_p); -} - -/* - * ------------------------------------------------------------------------- - * Functions used to send MIH link command messages - * ------------------------------------------------------------------------- - */ - -/**************************************************************************** - ** ** - ** Name: eRAL_send_get_parameters_confirm() ** - ** ** - ** Description: Sends a Link_Get_Parameters.confirm message to the MIHF. ** - ** ** - ** This primitive is generated in response to a Link_Get_ ** - ** Parameters.request. ** - ** ** - ** Inputs: tid_pP Transaction identifier ** - ** statusP: Status of operation ** - ** lparam_listP: List of measurable link parameters and ** - ** their current values ** - ** lstates_listP: List of current link state information ** - ** ldesc_listP: List of link descriptors ** - ** Others: g_enb_ral_obj[instanceP].link_id, g_enb_ral_obj[instanceP].mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRAL_send_get_parameters_confirm(ral_enb_instance_t instanceP, MIH_C_TRANSACTION_ID_T *tid_pP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_PARAM_LIST_T *lparam_listP, - MIH_C_LINK_STATES_RSP_LIST_T *lstates_listP, - MIH_C_LINK_DESC_RSP_LIST_T *ldesc_listP) -{ - MIH_C_Message_Link_Get_Parameters_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_GET_PARAMETERS_CONFIRM\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Get_Parameters_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[instanceP].link_id, strlen(g_enb_ral_obj[instanceP].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[instanceP].mihf_id, strlen(g_enb_ral_obj[instanceP].mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.LinkParametersStatusList_list = lparam_listP; - message.primitive.LinkStatesResponse_list = lstates_listP; - message.primitive.LinkDescriptorsResponse_list = ldesc_listP; - - message_total_length = MIH_C_Link_Message_Encode_Get_Parameters_confirm(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Get_Parameters.confirm\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Get_Parameters.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_send_configure_thresholds_confirm() ** - ** ** - ** Description: Sends a Link_Configure_Thresholds.confirm message to the ** - ** MIHF. ** - ** ** - ** This primitive is generated in response to a Link_ ** - ** Configure_Thresholds.request. ** - ** ** - ** Inputs: tid_pP Transaction identifier ** - ** statusP: Status of operation ** - ** lstatus_listP: List of link configure status ** - ** Others: g_enb_ral_obj[instanceP].link_id, g_enb_ral_obj[instanceP].mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRAL_send_configure_thresholds_confirm(ral_enb_instance_t instanceP, MIH_C_TRANSACTION_ID_T *tid_pP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_CFG_STATUS_LIST_T *lstatus_listP) -{ - MIH_C_Message_Link_Configure_Thresholds_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_CONFIRM\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Configure_Thresholds_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)2; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[instanceP].link_id, strlen(g_enb_ral_obj[instanceP].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[instanceP].mihf_id, strlen(g_enb_ral_obj[instanceP].mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.LinkConfigureStatusList_list = lstatus_listP; - - message_total_length = MIH_C_Link_Message_Encode_Configure_Thresholds_confirm(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Configure_Threshold.confirm\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Configure_Threshold.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_send_link_action_confirm() ** - ** ** - ** Description: Sends a Link_Action.confirm message to the MIHF. ** - ** ** - ** This primitive is generated to communicate the result of ** - ** the action executed on the link-layer connection. ** - ** ** - ** Inputs: tid_pP Transaction identifier ** - ** statusP: Status of operation ** - ** response_setP: List of discovered links and related ** - ** information ** - ** action_resultP: Specifies whether the link action was ** - ** successful ** - ** Others: g_enb_ral_obj[instanceP].link_id, g_enb_ral_obj[instanceP].mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRAL_send_link_action_confirm( - ral_enb_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *tid_pP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_SCAN_RSP_LIST_T *response_setP, - MIH_C_LINK_AC_RESULT_T *action_resultP) -{ - MIH_C_Message_Link_Action_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - - LOG_D(RAL_ENB, " Send MIH_C_MESSAGE_LINK_ACTION_CONFIRM\n"); - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Action_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)3; - message.header.transaction_id = *tid_pP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_enb_ral_obj[instanceP].link_id, strlen(g_enb_ral_obj[instanceP].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_enb_ral_obj[instanceP].mihf_id, strlen(g_enb_ral_obj[instanceP].mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.ScanResponseSet_list = response_setP; - message.primitive.LinkActionResult = action_resultP; - - message_total_length = MIH_C_Link_Message_Encode_Link_Action_confirm(bb_p, &message); - - if (eRAL_send_to_mih( instanceP, bb_p->m_buffer, message_total_length) < 0) { - LOG_E(RAL_ENB, ": Send Link_Action.confirm\n"); - } else { - LOG_D(RAL_ENB, ": Sent Link_Action.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_mihf_connect(ral_enb_instance_t instanceP) ** - ** ** - ** Description: Connects the RAL to the remote MIH Function. ** - ** The calling process should exit upon connection failure ** - ** in order to properly close the MIH-F socket file ** - ** descriptor and free the automatically allocated addrinfo ** - ** structure. ** - ** ** - ** Inputs: None ** - ** Others: g_enb_ral_obj[instanceP].mihf_ip_address, g_enb_ral_obj[instanceP].mihf_remote_port ** - ** g_enb_ral_obj[instanceP].ral_ip_address, ** - ** g_enb_ral_obj[instanceP].ral_listening_port ** - ** ** - ** Outputs: None ** - ** Return: 0 on success, -1 on failure ** - ** Others: g_sockd_mihf ** - ** ** - ****************************************************************************/ -int eRAL_mihf_connect(ral_enb_instance_t instanceP) -{ - struct addrinfo info; /* endpoint information */ - struct addrinfo *addr, *rp; /* endpoint address */ - int rc; /* returned error code */ - int optval; /* socket option value */ - - unsigned char buf[sizeof(struct sockaddr_in6)]; - - /* - * Initialize the remote MIH-F endpoint address information - */ - memset(&info, 0, sizeof(struct addrinfo)); - info.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ - info.ai_socktype = SOCK_DGRAM; /* Datagram socket */ - info.ai_flags = 0; - info.ai_protocol = 0; /* Any protocol */ - - rc = getaddrinfo(g_enb_ral_obj[instanceP].mihf_ip_address, g_enb_ral_obj[instanceP].mihf_remote_port, &info, &addr); - - if (rc != 0) { - LOG_E(RAL_ENB, " getaddrinfo: %s\n", gai_strerror(rc)); - return -1; - } - - /* - * getaddrinfo() returns a linked list of address structures. - * Try each address until we successfully connect(2). If socket(2) - * (or connect(2)) fails, we (close the socket and) try the next address. - */ - for (rp = addr; rp != NULL; rp = rp->ai_next) { - - g_enb_ral_obj[instanceP].mih_sock_desc = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - - if (g_enb_ral_obj[instanceP].mih_sock_desc < 0) { - continue; - } - - optval = 1; - setsockopt(g_enb_ral_obj[instanceP].mih_sock_desc, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); - - /* - * Convert the RAL local network address - */ - if (rp->ai_family == AF_INET) { - /* IPv4 network address family */ - struct sockaddr_in *addr4 = NULL; - - LOG_D(RAL_ENB, " %s is an ipv4 address\n", g_enb_ral_obj[instanceP].mihf_ip_address); - addr4 = (struct sockaddr_in *)(&buf[0]); - addr4->sin_port = htons(atoi(g_enb_ral_obj[instanceP].ral_listening_port)); - addr4->sin_family = AF_INET; - rc = inet_pton(AF_INET, g_enb_ral_obj[instanceP].ral_ip_address, &addr4->sin_addr); - } else if (rp->ai_family == AF_INET6) { - /* IPv6 network address family */ - struct sockaddr_in6 *addr6 = NULL; - - LOG_D(RAL_ENB, " %s is an ipv6 address\n", g_enb_ral_obj[instanceP].mihf_ip_address); - addr6 = (struct sockaddr_in6 *)(&buf[0]); - addr6->sin6_port = htons(atoi(g_enb_ral_obj[instanceP].ral_listening_port)); - addr6->sin6_family = AF_INET6; - rc = inet_pton(AF_INET, g_enb_ral_obj[instanceP].ral_ip_address, &addr6->sin6_addr); - } else { - LOG_E(RAL_ENB, " %s is an unknown address format %d\n", - g_enb_ral_obj[instanceP].mihf_ip_address, rp->ai_family); - return -1; - } - - if (rc < 0) { - /* The network address convertion failed */ - LOG_E(RAL_ENB, " inet_pton(RAL IP address %s): %s\n", - g_enb_ral_obj[instanceP].ral_ip_address, strerror(rc)); - return -1; - } else if (rc == 0) { - /* The network address is not valid */ - LOG_E(RAL_ENB, " RAL IP address %s is not valid\n", g_enb_ral_obj[instanceP].ral_ip_address); - return -1; - } - - /* Bind the socket to the local RAL network address */ - rc = bind(g_enb_ral_obj[instanceP].mih_sock_desc, (const struct sockaddr *)buf, - sizeof(struct sockaddr_in)); - - if (rc < 0) { - LOG_E(RAL_ENB, " bind(RAL IP address %s): %s\n", - g_enb_ral_obj[instanceP].ral_ip_address, strerror(errno)); - return -1; - } - - /* Connect the socket to the remote MIH-F network address */ - if (connect(g_enb_ral_obj[instanceP].mih_sock_desc, rp->ai_addr, rp->ai_addrlen) == 0) { - LOG_N(RAL_ENB, " RAL [%s:%s] is now UDP-CONNECTED to MIH-F [%s:%s]\n", - g_enb_ral_obj[instanceP].ral_ip_address, g_enb_ral_obj[instanceP].ral_listening_port, - g_enb_ral_obj[instanceP].mihf_ip_address, g_enb_ral_obj[instanceP].mihf_remote_port); - break; - } - - /* - * We failed to connect: - * Close the socket file descriptor and try to connect to an other - * address. - */ - close(g_enb_ral_obj[instanceP].mih_sock_desc); - } - - /* - * Unable to connect to a network address - */ - if (rp == NULL) { - LOG_E(RAL_ENB, " Could not connect to MIH-F\n"); - return -1; - } - - freeaddrinfo(addr); - - return 0; -} - -/**************************************************************************** - ** Name: eRAL_mih_link_process_message() ** - ** Description: Processes messages received from the MIH-F. ** - ** Others: g_sockd_mihf ** - ** Return: Always return 0 ** - ** Others: g_msg_codec_recv_buffer ** - ***************************************************************************/ -int eRAL_mih_link_process_message(ral_enb_instance_t instanceP) -{ - MIH_C_Message_Wrapper_t message_wrapper; - int nb_bytes_received ; - int nb_bytes_decoded ; - int total_bytes_to_decode ; - int status ; - Bit_Buffer_t *bb_p; - struct sockaddr_in udp_socket; - socklen_t sockaddr_len; - - LOG_D(RAL_ENB,"HEEERRRE process mesage\n"); - - total_bytes_to_decode = 0; - nb_bytes_received = 0; - - bb_p = new_BitBuffer_0(); - - nb_bytes_received = recvfrom(g_enb_ral_obj[instanceP].mih_sock_desc, - (void *)g_msg_codec_recv_buffer, - MSG_CODEC_RECV_BUFFER_SIZE, - 0, - (struct sockaddr *) &udp_socket, - &sockaddr_len); - - if (nb_bytes_received > 0) { - LOG_D(RAL_ENB, " \n"); - LOG_D(RAL_ENB, " %s Received %d bytes\n", __FUNCTION__, nb_bytes_received); - eRAL_print_buffer(g_msg_codec_recv_buffer, nb_bytes_received); - total_bytes_to_decode += nb_bytes_received; - BitBuffer_wrap(bb_p, g_msg_codec_recv_buffer, total_bytes_to_decode); - /* Decode the message received from the MIHF */ - status = eRAL_mih_link_msg_decode(instanceP, bb_p, &message_wrapper); - - if (status == MIH_MESSAGE_DECODE_OK) { - nb_bytes_decoded = BitBuffer_getPosition(bb_p); - - if (nb_bytes_decoded > 0) { - total_bytes_to_decode = total_bytes_to_decode - nb_bytes_decoded; - - // if remaining bytes to decode - if (total_bytes_to_decode > 0) { - //shift left bytes in buffer - memcpy(g_msg_codec_recv_buffer, &g_msg_codec_recv_buffer[nb_bytes_decoded], nb_bytes_decoded); - - //shift left again bytes in buffer - if (total_bytes_to_decode > nb_bytes_decoded) { - memcpy(&g_msg_codec_recv_buffer[nb_bytes_decoded], &g_msg_codec_recv_buffer[nb_bytes_decoded], total_bytes_to_decode - nb_bytes_decoded); - } - - // not necessary - memset(&g_msg_codec_recv_buffer[total_bytes_to_decode], 0 , MSG_CODEC_RECV_BUFFER_SIZE - total_bytes_to_decode); - } - } - - // data could not be decoded - } else if (status == MIH_MESSAGE_DECODE_FAILURE) { - memset(g_msg_codec_recv_buffer, 0, MSG_CODEC_RECV_BUFFER_SIZE); - total_bytes_to_decode = 0; - } else if (status == MIH_MESSAGE_DECODE_TOO_SHORT) { - } else if (status == MIH_MESSAGE_DECODE_BAD_PARAMETER) { - } - } - - free_BitBuffer(bb_p); - return 0; -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRAL_print_buffer() ** - ** ** - ** Description: Print the content of a buffer in hexadecimal. ** - ** ** - ** Inputs: buffer_pP: Pointer to the buffer to print ** - ** lengthP: Length of the buffer to print ** - ** Others: g_msg_codec_print_buffer ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void eRAL_print_buffer(const u_int8_t * buffer_pP, int lenP) -{ - char c; - unsigned int buffer_index = 0; - unsigned int index; - unsigned int octet_index = 0; - unsigned long char_index = 0; - - if (buffer_pP == NULL) { - return; - } - - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index],"\n------+-------------------------------------------------+------------------+\n"); - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " | 0 1 2 3 4 5 6 7 8 9 a b c d e f | 0123456789abcdef |\n"); - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], "------+-------------------------------------------------+------------------+\n"); - - for (octet_index = 0; octet_index < lenP; octet_index++) { - if ((octet_index % 16) == 0) { - if (octet_index != 0) { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " | "); - - for (char_index = octet_index - 16; char_index < octet_index; char_index++) { - c = (char) buffer_pP[char_index] & 0177; - - if (iscntrl(c) || isspace(c)) { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " "); - } else { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], "%c", c); - } - } - - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " |\n"); - } - - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " %04d |", octet_index); - } - - /* - * Print every single octet in hexadecimal form - */ - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " %02x", (u_int8_t)(buffer_pP[octet_index] & 0x00FF)); - } - - /* - * Append enough spaces and put final pipe - */ - if ((lenP % 16) > 0) { - for (index = (octet_index % 16); index < 16; ++index) { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " "); - } - } - - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " | "); - - for (char_index = (octet_index / 16) * 16; char_index < octet_index; char_index++) { - c = (char) buffer_pP[char_index] & 0177; - - if (iscntrl(c) || isspace(c)) { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " "); - } else { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], "%c", c); - } - } - - if ((lenP % 16) > 0) { - for (index = (octet_index % 16); index < 16; ++index) { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " "); - } - } - - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " |\n"); - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], "------+-------------------------------------------------+------------------+\n"); - LOG_D(RAL_ENB, g_msg_codec_print_buffer); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_send_to_mih( instanceP, ) ** - ** ** - ** Description: Sends a buffered message to the MIH-F. ** - ** ** - ** Inputs: buffer_pP: Pointer to the buffered buffer to send ** - ** lenP: Length of the buffered buffer to send ** - ** Others: g_sockd_mihf ** - ** ** - ** Outputs: None ** - ** Return: The number of bytes actually sent ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRAL_send_to_mih(ral_enb_instance_t instanceP, const u_int8_t *buffer_pP, int lenP) -{ - int result; - eRAL_print_buffer(buffer_pP, lenP); - result = send(g_enb_ral_obj[instanceP].mih_sock_desc, (const void *)buffer_pP, lenP, 0); - - if (result != lenP) { - LOG_E(RAL_ENB, " %s : %d bytes failed, returned %d: %s\n", - __FUNCTION__, lenP, result, strerror(errno)); - } - - return result; -} - -/**************************************************************************** - ** Name: eRAL_mih_link_msg_decode() ** - ** Description: Decode messages received from the MIH-F. ** - ** Inputs: bb_pP: Pointer to the buffer to decode ** - ** Outputs: message_wrapper_pP: ** - ** Pointer to the message wrapper ** - ** Return: < 0 on failure, 0 otherwise ** - ***************************************************************************/ -int eRAL_mih_link_msg_decode(ral_enb_instance_t instanceP, Bit_Buffer_t* bb_pP, MIH_C_Message_Wrapper_t *message_wrapper_pP) -{ - //--------------------------------------------------------------------------- - int status = MIH_MESSAGE_DECODE_FAILURE; - MIH_C_HEADER_T header; - MIH_C_STATUS_T mih_status; - - LOG_D(RAL_ENB,"HEEERRRE decode\n"); - - if ((bb_pP != NULL) && (message_wrapper_pP != NULL)) { - /* - * Decode MIH protocol header - */ - status = MIH_C_Link_Header_Decode(bb_pP, &header); - - if (status == MIH_HEADER_DECODE_TOO_SHORT) { - return MIH_MESSAGE_DECODE_TOO_SHORT; - } else if (status == MIH_HEADER_DECODE_FAILURE) { - return MIH_MESSAGE_DECODE_FAILURE; - } else if (status == MIH_HEADER_DECODE_BAD_PARAMETER) { - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - message_wrapper_pP->message_id = MIH_C_MESSAGE_ID(header.service_identifier, header.operation_code, header.action_identifier); - - /* - * Decode MIH primitives - */ - - switch (message_wrapper_pP->message_id) { - - case MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_REQUEST_ID: - /* - * This primitive is generated by the MIHF when it needs to - * receive link-layer event notifications and learn about which - * link-layer commands the lower layer can support. - * The recipient responds immediately with Link_Capability_ - * Discover.confirm primitive. - */ - LOG_D(RAL_ENB, " %s Received MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapper_pP->_union_message.link_capability_discover_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Capability_Discover.request */ - status = MIH_C_Link_Message_Decode_Link_Capability_Discover_request(bb_pP, &message_wrapper_pP->_union_message.link_capability_discover_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - - /* Process Link_Capability_Discover.request */ - MIH_C_Link_Message_Link_Capability_Discover_request2String(&message_wrapper_pP->_union_message.link_capability_discover_request, g_msg_print_buffer); - LOG_D(RAL_ENB, " %s", g_msg_print_buffer); - mih_status = MIH_C_STATUS_SUCCESS; - LOG_D(RAL_ENB, "**\n"); - /* Send Link_Capability_Discover.confirm */ - eRAL_send_capability_discover_confirm(instanceP, &message_wrapper_pP->_union_message.link_capability_discover_request.header.transaction_id, - &mih_status, - &g_enb_ral_obj[instanceP].mih_supported_link_event_list, - &g_enb_ral_obj[instanceP].mih_supported_link_command_list); - } else { - } - - break; - - case MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_REQUEST_ID: - /* - * This primitive is generated by a subscriber such as the MIHF - * that is seeking to receive event indications from different - * link-layer technologies. - * The recipient responds immediately with Link_Event_Subscribe. - * confirm primitive. - */ - LOG_D(RAL_ENB, " %s Received MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapper_pP->_union_message.link_event_subscribe_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Event_Subscribe.request */ - status = MIH_C_Link_Message_Decode_Link_Event_Subscribe_request(bb_pP, &message_wrapper_pP->_union_message.link_event_subscribe_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - /* Process Link_Event_Subscribe.request */ - LOG_D(RAL_ENB, "**\n"); - eRAL_subscribe_request(instanceP, &message_wrapper_pP->_union_message.link_event_subscribe_request); - - } else { - } - - break; - - case MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_REQUEST_ID: - /* - * This primitive is generated by a subscriber such as the MIHF - * that is seeking to unsubscribe from an already subscribed set - * of events. - * The recipient responds immediately with Link_Event_ - * Unsubscribe.confirm primitive. - */ - LOG_D(RAL_ENB, " %s Received MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapper_pP->_union_message.link_event_unsubscribe_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Event_Unsubscribe.request */ - status = MIH_C_Link_Message_Decode_Link_Event_Unsubscribe_request(bb_pP, &message_wrapper_pP->_union_message.link_event_unsubscribe_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - LOG_D(RAL_ENB, "**\n"); - /* Process Link_Event_Unsubscribe.request */ - eRAL_unsubscribe_request(instanceP, &message_wrapper_pP->_union_message.link_event_unsubscribe_request); - - } else { - } - - break; - - case MIH_C_MESSAGE_LINK_GET_PARAMETERS_REQUEST_ID: - /* - * This primitive is generated by the MIHF to obtain the current - * value of a set of link parameters from a link. - * The recipient link responds with Link_Get_Parameters.confirm - * primitive. - */ - LOG_D(RAL_ENB, " %s Received MIH_C_MESSAGE_LINK_GET_PARAMETERS_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapper_pP->_union_message.link_get_parameters_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Get_Parameters.request */ - status = MIH_C_Link_Message_Decode_Link_Get_Parameters_request(bb_pP, &message_wrapper_pP->_union_message.link_get_parameters_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - LOG_D(RAL_ENB, "**\n"); - /* Process Link_Get_Parameters.request */ - eRAL_get_parameters_request(instanceP, &message_wrapper_pP->_union_message.link_get_parameters_request); - } else { - } - - break; - - case MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_REQUEST_ID: - /* - * This primitive is generated by an MIHF that needs to set - * threshold values for different link parameters. - * The recipient responds immediately with Link_Configure_ - * Thresholds.confirm primitive. - */ - LOG_D(RAL_ENB, " %s Received MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapper_pP->_union_message.link_configure_thresholds_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Configure_Thresholds.request */ - status = MIH_C_Link_Message_Decode_Link_Configure_Thresholds_request(bb_pP, &message_wrapper_pP->_union_message.link_configure_thresholds_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - LOG_D(RAL_ENB, "**\n"); - /* Process Link_Configure_Thresholds.request */ - eRAL_configure_thresholds_request(instanceP, &message_wrapper_pP->_union_message.link_configure_thresholds_request); - } else { - } - - break; - - case MIH_C_MESSAGE_LINK_ACTION_REQUEST_ID: - /* - * This primitive is used by the MIHF to request an action on a - * link-layer connection to enable optimal handling of link- - * layer resources for the purpose of handovers. - * The MIHF generates this primitive upon request from the MIH - * user to perform an action on a pre-defined link-layer - * connection. - */ - LOG_D(RAL_ENB, " %s Received MIH_C_MESSAGE_LINK_ACTION_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapper_pP->_union_message.link_action_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Action.request */ - status = MIH_C_Link_Message_Decode_Link_Action_request(bb_pP, &message_wrapper_pP->_union_message.link_action_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - LOG_D(RAL_ENB, "**\n"); - /* Process Link_Action.request */ - eRAL_action_request(instanceP, &message_wrapper_pP->_union_message.link_action_request); - } else { - } - - break; - - default: - LOG_W(RAL_ENB, " UNKNOWN MESSAGE ID SID %d, OP_CODE %d, AID %d\n", header.service_identifier, header.operation_code, header.action_identifier); - status = MIH_MESSAGE_DECODE_FAILURE; - - return status; - } - } else { - status = MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - return status; -} diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_parameters.c b/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_parameters.c deleted file mode 100755 index e123436361..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_parameters.c +++ /dev/null @@ -1,182 +0,0 @@ -/***************************************************************************** - * Eurecom OpenAirInterface 3 - * Copyright(c) 2012 Eurecom - * - * Source eRAL_parameters.c - * - * Version 0.1 - * - * Date 07/03/2012 - * - * Product MIH RAL LTE - * - * Subsystem - * - * Authors Michelle Wetterwald, Lionel Gauthier, Frederic Maurel - * - * Description - * - *****************************************************************************/ -#define LTE_RAL_ENB -#define LTE_RAL_ENB_PARAMETERS_C - -#include "lteRALenb.h" - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRAL_get_parameters_request() ** - ** ** - ** Description: Processes the Link_Get_Parameters.request message and ** - ** sends a LinK_Get_Parameters.confirm message to the MIHF. ** - ** ** - ** Inputs: msgP: Pointer to the received message ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void eRAL_get_parameters_request(ral_enb_instance_t instanceP, MIH_C_Message_Link_Get_Parameters_request_t* messageP) -{ - MIH_C_STATUS_T status; - MIH_C_LINK_PARAM_LIST_T link_parameters_status_list; - MIH_C_LINK_STATES_RSP_LIST_T link_states_response_list; - MIH_C_LINK_DESC_RSP_LIST_T link_descriptors_response_list; - unsigned int link_index; - - // SAVE REQUEST - // MAY BE MERGE REQUESTS ? - //memcpy(&g_link_cfg_param_thresholds_list, &messageP->primitive.LinkConfigureParameterList_list, sizeof(MIH_C_LINK_CFG_PARAM_LIST_T)); - - status = MIH_C_STATUS_SUCCESS; - - for (link_index = 0; - link_index < messageP->primitive.LinkParametersRequest_list.length; - link_index++) { - - //------------------------------------------------ - // MIH_C_LINK_PARAM_LIST_T - //------------------------------------------------ - memcpy(&link_parameters_status_list.val[link_index].link_param_type, - &messageP->primitive.LinkParametersRequest_list.val[link_index], - sizeof(MIH_C_LINK_PARAM_TYPE_T)); - - switch (messageP->primitive.LinkParametersRequest_list.val[link_index].choice) { - case MIH_C_LINK_PARAM_TYPE_CHOICE_GEN: - /*#define MIH_C_LINK_PARAM_GEN_DATA_RATE (MIH_C_LINK_PARAM_GEN_T)0 - #define MIH_C_LINK_PARAM_GEN_SIGNAL_STRENGTH (MIH_C_LINK_PARAM_GEN_T)1 - #define MIH_C_LINK_PARAM_GEN_SINR (MIH_C_LINK_PARAM_GEN_T)2 - #define MIH_C_LINK_PARAM_GEN_THROUGHPUT (MIH_C_LINK_PARAM_GEN_T)3 - #define MIH_C_LINK_PARAM_GEN_PACKET_ERROR_RATE (MIH_C_LINK_PARAM_GEN_T)4*/ - link_parameters_status_list.val[link_index].choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - link_parameters_status_list.val[link_index]._union.link_param_val = MIH_C_LINK_PARAM_GEN_SIGNAL_STRENGTH; - break; - - case MIH_C_LINK_PARAM_TYPE_CHOICE_QOS: - /* - * \brief A type to represent QOS_LIST parameters. - * 0: Maximum number of differentiable classes of service supported. - * 1: Minimum packet transfer delay for all CoS, the minimum delay over a class - * population of interest. - * 2: Average packet transfer delay for all CoS, the arithmetic mean of the delay - * over a class population of interest. (See B.3.4) - * 3: Maximum packet transfer delay for all CoS, the maximum delay over a class - * population of interest. - * 4: Packet transfer delay jitter for all CoS, the standard deviation of the delay - * over a class population of interest. (See B.3.5.) - * 5: Packet loss rate for all CoS, the ratio between the number of frames that are - * transmitted but not received and the total number of frames transmitted over - * a class population of interest. (See B.3.2.) - * 6–255: (Reserved) - */ - link_parameters_status_list.val[link_index].choice = MIH_C_LINK_PARAM_CHOICE_QOS_PARAM_VAL; - link_parameters_status_list.val[link_index]._union.qos_param_val.choice = MIH_C_QOS_PARAM_VAL_CHOICE_AVG_PK_TX_DELAY; - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.length = 2; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[0].cos_id = 2; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[0].value = 20; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[1].cos_id = 3; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[2].value = 50; //?? - break; - - case MIH_C_LINK_PARAM_TYPE_CHOICE_LTE: - - /* - #define MIH_C_LINK_PARAM_LTE_UE_RSRP 0 - #define MIH_C_LINK_PARAM_LTE_UE_RSRQ 1 - #define MIH_C_LINK_PARAM_LTE_UE_CQI 2 - #define MIH_C_LINK_PARAM_LTE_AVAILABLE_BW 3 - #define MIH_C_LINK_PARAM_LTE_PACKET_DELAY 4 - #define MIH_C_LINK_PARAM_LTE_PACKET_LOSS_RATE 5 - #define MIH_C_LINK_PARAM_LTE_L2_BUFFER_STATUS 6 - #define MIH_C_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES 7 - #define MIH_C_LINK_PARAM_LTE_EMBMS_CAPABILITY 8 - #define MIH_C_LINK_PARAM_LTE_JUMBO_FEASIBILITY 9 - #define MIH_C_LINK_PARAM_LTE_JUMBO_SETUP_STATUS 10 - #define MIH_C_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW 11 - */ - case MIH_C_LINK_PARAM_TYPE_CHOICE_GG: - case MIH_C_LINK_PARAM_TYPE_CHOICE_EDGE: - case MIH_C_LINK_PARAM_TYPE_CHOICE_ETH: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_11: - case MIH_C_LINK_PARAM_TYPE_CHOICE_C2K: - case MIH_C_LINK_PARAM_TYPE_CHOICE_FDD: - case MIH_C_LINK_PARAM_TYPE_CHOICE_HRPD: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_16: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_20: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_22: - default: - LOG_E(RAL_ENB, "%s TO DO CONTINUE PROCESSING LinkParametersRequest_list of \n", __FUNCTION__); - } - - //------------------------------------------------ - // MIH_C_LINK_STATES_RSP_LIST_T - //------------------------------------------------ - if (messageP->primitive.LinkStatesRequest & MIH_C_BIT_LINK_STATES_REQ_OP_MODE) { - link_states_response_list.val[link_index].choice = 0; - link_states_response_list.val[link_index]._union.op_mode = MIH_C_OPMODE_NORMAL_MODE; - } else if (messageP->primitive.LinkStatesRequest & MIH_C_BIT_LINK_STATES_REQ_CHANNEL_ID) { - link_states_response_list.val[link_index].choice = 1; - link_states_response_list.val[link_index]._union.channel_id = PREDEFINED_CHANNEL_ID; - } else { - LOG_E(RAL_ENB, "%s Invalid LinkStatesRequest in MIH_C_Link_Get_Parameters_request\n", __FUNCTION__); - // DEFAULT VALUES - link_states_response_list.val[link_index].choice = 0; - link_states_response_list.val[link_index]._union.op_mode = MIH_C_OPMODE_NORMAL_MODE; - } - - //------------------------------------------------ - // MIH_C_LINK_DESC_RSP_LIST_T - //------------------------------------------------ - if (messageP->primitive.LinkDescriptorsRequest & MIH_C_BIT_NUMBER_OF_CLASSES_OF_SERVICE_SUPPORTED) { - link_descriptors_response_list.val[link_index].choice = 0; - link_descriptors_response_list.val[link_index]._union.num_cos = PREDEFINED_CLASSES_SERVICE_SUPPORTED; - } else if (messageP->primitive.LinkDescriptorsRequest & MIH_C_BIT_NUMBER_OF_QUEUES_SUPPORTED) { - link_descriptors_response_list.val[link_index].choice = 1; - link_descriptors_response_list.val[link_index]._union.num_queue = PREDEFINED_QUEUES_SUPPORTED; - } else { - LOG_E(RAL_ENB, "%s Invalid LinkDescriptorsRequest in MIH_C_Link_Get_Parameters_request\n", __FUNCTION__); - // DEFAULT VALUES - link_descriptors_response_list.val[link_index].choice = 0; - link_descriptors_response_list.val[link_index]._union.num_cos = PREDEFINED_CLASSES_SERVICE_SUPPORTED; - } - } - - link_parameters_status_list.length = messageP->primitive.LinkParametersRequest_list.length; - link_states_response_list.length = messageP->primitive.LinkParametersRequest_list.length; - link_descriptors_response_list.length = messageP->primitive.LinkParametersRequest_list.length; - - /* Get parameters link command is not supported at the network side */ - LOG_D(RAL_ENB, " Get Parameters request is not supported by the network\n"); - eRAL_send_get_parameters_confirm(instanceP, &messageP->header.transaction_id, - &status, NULL, NULL, NULL); -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_process.c b/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_process.c deleted file mode 100755 index a745f85f3d..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_process.c +++ /dev/null @@ -1,670 +0,0 @@ -/***************************************************************************** - * Eurecom OpenAirInterface 3 - * Copyright(c) 2012 Eurecom - * - * Source eRAL_process.c - * - * Version 0.1 - * - * Date 07/10/2012 - * - * Product MIH RAL LTE - * - * Subsystem - * - * Authors Michelle Wetterwald, Lionel Gauthier, Frederic Maurel - * - * Description - * - *****************************************************************************/ -#define LTE_RAL_ENB -#define LTE_RAL_ENB_PROCESS_C -#include "lteRALenb.h" - - - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRAL_process_find_channel() ** - ** ** - ** Description: Returns the Mobile Terminal index and the Radio Bearer ** - ** channel index for the specified Connection identifier. ** - ** ** - ** Inputs: cnxid: Connection identifier ** - ** Others: ralpriv ** - ** ** - ** Outputs: mt_ix: Mobile Terminal index ** - ** ch_ix: Radio Bearer channel index ** - ** Return: 0 if no MT and RB channel indexes exist ** - ** for the specified Connection identifier. ** - ** 1 otherwise. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRAL_process_find_channel(ral_enb_instance_t instanceP, unsigned int cnxid, int* mt_ix, int* ch_ix) -{ - int mt, ch; - int found = 0; - - LOG_D(RAL_ENB, " %s : cnxid = %d\n", __FUNCTION__, cnxid); - - for (mt = 0; !found && (mt < RAL_MAX_MT); mt++) { - for (ch = 0; ch < RAL_MAX_RB; ch++) { - if (g_enb_ral_obj[instanceP].mt[mt].radio_channel[ch].cnx_id == cnxid) { - found = 1; - *mt_ix = mt; - *ch_ix = ch; - break; - } - } - } - - if (!found) { - *mt_ix = RAL_MAX_MT; - *ch_ix = 0; - } - - LOG_D(RAL_ENB, " %s : return %d (mt=%d, ch=%d)\n" , __FUNCTION__, found, *mt_ix, *ch_ix); - return found; -} - -/**************************************************************************** - ** ** - ** Name: eRAL_process_find_new_channel() ** - ** ** - ** Description: Returns the index of the first available Radio Bearer ** - ** channel for the specified Mobile Terminal identifier. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: The index of the first available RB chan- ** - ** nel; RAL_MAX_RB if no any RB channel is ** - ** available. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRAL_process_find_new_channel(ral_enb_instance_t instanceP, int mt_ix) -{ - int ch_ix; - - LOG_D(RAL_ENB, " %s : mt_ix = %d\n", __FUNCTION__, mt_ix); - - for (ch_ix = 0; ch_ix < RAL_MAX_RB; ch_ix++) { - if (g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix].cnx_id == 0) { - break; - } - } - - LOG_D(RAL_ENB, " %s : return %d\n" , __FUNCTION__, ch_ix); - return ch_ix; -} - -/**************************************************************************** - ** ** - ** Name: eRAL_process_clean_channel() ** - ** ** - ** Description: Cleans data of the specified Radio Bearer channel. ** - ** ** - ** Inputs: None ** - ** Others: None ** - ** ** - ** Outputs: channel: Channel data to clean ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void eRAL_process_clean_channel(struct ral_lte_channel* channel) -{ - LOG_D(RAL_ENB, " %s : cnx_id = %d, rbId = %d\n", __FUNCTION__, - channel->cnx_id, channel->rbId); - memset(channel, 0, sizeof (struct ral_lte_channel)); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_process_mt_addr_to_string() ** - ** ** - ** Description: Display the specified IPv6 address. ** - ** ** - ** Inputs: ip_addr: The IP address ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: Pointer to the string buffer. ** - ** Others: None ** - ** ** - ***************************************************************************/ -char* eRAL_process_mt_addr_to_string(const unsigned char* ip_addr) -{ - static char buffer[40]; - int i, index = 0; - - for (i = 0; i < 16; i++) { - index += sprintf(&buffer[index], "%.2hhX", ip_addr[i]); - - if (i % 2) buffer[index++] = ':'; - } - - buffer[--index] = '\0'; - return buffer; -} - -/**************************************************************************** - ** ** - ** Name: eRAL_process_mt_addr_to_l2id() ** - ** ** - ** Description: Convert the specified IP address to Layer 2 identifier. ** - ** ** - ** Inputs: mt_addr: MT's IP address ** - ** Others: None ** - ** ** - ** Outputs: l2id Layer 2 identifier ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void eRAL_process_mt_addr_to_l2id(const unsigned char* mt_addr, unsigned int* l2id) -{ - if ( !(mt_addr) || !(l2id) ) { - LOG_E(RAL_ENB, " %s : input parameter is NULL\n", __FUNCTION__); - return; - } - - l2id[0] = mt_addr[0]+256 *(mt_addr[1]+256*(mt_addr[2]+256*(mt_addr[3]))); - l2id[1] = mt_addr[4]+256 *(mt_addr[5]+256*(mt_addr[6]+256*(mt_addr[7]))); -} - -/**************************************************************************** - ** ** - ** Name: eRAL_process_cmp_mt_addr() ** - ** ** - ** Description: Compares MT's IP address to the specified L2 identifier. ** - ** ** - ** Inputs: mt_addr: MT's IP address ** - ** l2id Layer 2 identifier ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: 0 if the MT's IP address matches the L2 ** - ** identifier, 1 otherwise. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRAL_process_cmp_mt_addr(const char* mt_addr, const char* l2id) -{ - int i; - - for (i = 0; i < 8; i++) { - if ((uint8_t)l2id[i] != (uint8_t)mt_addr[i+8]) { - return 0; - } - } - - return 1; -} - -/**************************************************************************** - ** ** - ** Name: eRAL_process_find_mt_by_addr() ** - ** ** - ** Description: Returns the index of the Mobile Terminal with the ** - ** specified IP address. ** - ** ** - ** Inputs: mt_addr: MT's IP address ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: The MT's index in the list of MTs; ** - ** RAL_MAX_MT if not found. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRAL_process_find_mt_by_addr(ral_enb_instance_t instanceP, const char* mt_addr) -{ - int mt_ix; - - for (mt_ix = 0; mt_ix < RAL_MAX_MT; mt_ix++) { - const char* l2id = (const char*)(&g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_l2id[0]); - int i; - - for (i = 0; i < 8; i++) { - if ((uint8_t)l2id[i] != (uint8_t)mt_addr[i+8]) { - break; - } - } - - if (i == 8) { - break; - } - } - - LOG_D(RAL_ENB, " %s : return %d\n" , __FUNCTION__, mt_ix); - return mt_ix; -} - -/**************************************************************************** - ** ** - ** Name: eRAL_process_verify_pending_mt_status() ** - ** ** - ** Description: Checks the pending MT connection status and simulates RB ** - ** setup if it is ready for Radio Bearer establishment. ** - ** ** - ** Inputs: None ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void eRAL_process_verify_pending_mt_status(ral_enb_instance_t instanceP) -{ - int mt_ix; - - if (!g_enb_ral_obj[instanceP].pending_mt_timer) { - LOG_D(RAL_ENB, " Pending MT timer expired\n"); -#ifdef RAL_REALTIME - eRAL_process_clean_pending_mt(instanceP); -#endif -#ifdef RAL_DUMMY - LOG_D(RAL_ENB, " SIMULATE MT arrival\n"); - mt_ix = eRAL_NAS_update_MTs_list(); - LOG_D(RAL_ENB, " SIMULATE RB setup\n"); - eRAL_process_waiting_RB(mt_ix); -#endif - } else { -#ifdef RAL_REALTIME - - if (!( g_enb_ral_obj[instanceP].pending_mt_timer % 10)) { - /* Get the list of MTs in the driver waiting for pending - * RB establishment */ - // LG RAL_process_NAS_message(IO_OBJ_CNX, IO_CMD_LIST, 0, 0); - // LG RAL_process_NAS_message(IO_OBJ_RB, IO_CMD_LIST, 0, 0); - /* Check if the pending MT is in the list */ - mt_ix = eRAL_process_find_mt_by_addr(instanceP, (char*)g_enb_ral_obj[instanceP].pending_mt.ipv6_addr); - - if ( (mt_ix < RAL_MAX_MT) && - (g_enb_ral_obj[instanceP].mt[mt_ix].mt_state == RB_CONNECTED)) { - /* The pending MT is ready for RB establishment */ - eRAL_process_waiting_RB(instanceP, mt_ix); - } - } - -#endif - } -} - -/**************************************************************************** - ** ** - ** Name: eRAL_process_map_qos() ** - ** ** - ** Description: Performs mapping of reserved bit rate to Radio QoS class, ** - ** and mapping of traffic class to DCSP. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** ch_ix: Radio Bearer channel index ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: 1 if the requested reserved bit rate and ** - ** traffic class are supported and their ** - ** mapping to Radio Qos class and DSCP ** - ** succeed. 0 otherwise. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -int eRAL_process_map_qos(ral_enb_instance_t instanceP, int mt_ix, int ch_ix) -{ - int resBitrateDL = 0, resBitrateUL = 0; - struct ral_lte_channel *currChannel; - - /* - * Map for multicast flow - */ - if (mt_ix == RAL_MAX_MT) { - currChannel = &(g_enb_ral_obj[instanceP].mcast.radio_channel); - - /* multicast - reserved bit rate */ - resBitrateDL = (int)currChannel->resBitrate[1]; - - if (resBitrateDL <= RAL_BITRATE_128k) { - currChannel->RadioQoSclass = 20; - } else if (resBitrateDL <= RAL_BITRATE_256k) { - currChannel->RadioQoSclass = 21; - } else if (resBitrateDL <= RAL_BITRATE_384k) { - currChannel->RadioQoSclass = 22; - } else { - LOG_E(RAL_ENB, " %s : Invalid requested resBitrate %d - Request will be rejected.\n", __FUNCTION__, resBitrateDL); - return 0; - } - - /* multicast - DSCP */ - if (currChannel->classId[1] < 64) { - currChannel->dscpDL = currChannel->classId[1]; - } else { - LOG_E(RAL_ENB, " %s : DSCP %d > 63 - NOT SUPPORTED - Request will be rejected.\n", __FUNCTION__, currChannel->classId[1]); - return 0; - } - - LOG_D(RAL_ENB, " QoS Mapping : Requested radio QoS class %d, DSCP DL %d\n", - currChannel->RadioQoSclass, - currChannel->dscpDL); - } - - /* - * Map for unicast flow - */ - else { - currChannel = &(g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix]); - - /* unicast - reserved bit rate - CONVERSATIONAL */ - resBitrateDL = (int)currChannel->resBitrate[1]; - resBitrateUL = (int)currChannel->resBitrate[0]; - - if ((resBitrateDL <= RAL_BITRATE_32k) && - (resBitrateUL <= RAL_BITRATE_32k)) { - currChannel->RadioQoSclass = 1; - } else if ((resBitrateDL <= RAL_BITRATE_64k) && - (resBitrateUL <= RAL_BITRATE_64k)) { - currChannel->RadioQoSclass = 2; - } else if ((resBitrateDL <= RAL_BITRATE_128k) && - (resBitrateUL <= RAL_BITRATE_128k)) { - currChannel->RadioQoSclass = 3; - } else if ((resBitrateDL <= RAL_BITRATE_256k) && - (resBitrateUL <= RAL_BITRATE_256k)) { - currChannel->RadioQoSclass = 4; - } else if ((resBitrateDL <= RAL_BITRATE_320k) && - (resBitrateUL <= RAL_BITRATE_320k)) { - currChannel->RadioQoSclass = 5; - } else if ((resBitrateDL >= RAL_BITRATE_384k) && - (resBitrateDL <= RAL_BITRATE_440k) && - (resBitrateUL <= RAL_BITRATE_64k)) { - currChannel->RadioQoSclass = 14; - } else { - LOG_E(RAL_ENB, " %s : Invalid requested resBitrate %d , %d - Request will be rejected\n", __FUNCTION__, resBitrateDL, resBitrateUL); - return 0; - } - - /* unicast - DSCP */ - if ((currChannel->classId[0] < 64) && - (currChannel->classId[1] < 64)) { - currChannel->dscpUL = currChannel->classId[0]; - currChannel->dscpDL = currChannel->classId[1]; - } else { - LOG_E(RAL_ENB, " %s : DSCP > 63 - NOT SUPPORTED - Request will be rejected.\n", __FUNCTION__); - return 0; - } - - LOG_D(RAL_ENB, " QoS Mapping : Requested radio QoS class %d, DSCP UL %d, DSCP DL %d\n", currChannel->RadioQoSclass, currChannel->dscpUL, currChannel->dscpDL); - } - - return 1; -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRAL_process_waiting_RB() ** - ** ** - ** Description: Allocates a new Radio Bearer parameters to the specified ** - ** Mobile Terminal which was pending for RB establishment, ** - ** and sends RB establishment request to the NAS sublayer. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -void eRAL_process_waiting_RB(ral_enb_instance_t instanceP, int mt_ix) -{ - struct ral_lte_channel *currChannel; - struct ral_lte_channel *pendingChannel; - int ch_ix, f_ix; - int dir, mapping_result, rc = -1; - - LOG_D(RAL_ENB, " Establishment of pending RB now starting...\n"); - ch_ix = eRAL_process_find_new_channel(instanceP, mt_ix); - - if (ch_ix == RAL_MAX_RB) { - LOG_D(RAL_ENB, " No RB available in MT - Deleting request data\n"); - eRAL_process_clean_pending_mt(instanceP); - return; - } - - pendingChannel = &(g_enb_ral_obj[instanceP].pending_mt.radio_channel[0]); - currChannel = &(g_enb_ral_obj[instanceP].mt[mt_ix].radio_channel[ch_ix]); - - currChannel->cnx_id = (RAL_MAX_RB_PER_UE*mt_ix)+ch_ix+1; - currChannel->rbId = RAL_DEFAULT_RAB_ID+ch_ix; - currChannel->multicast = 0; - LOG_D(RAL_ENB, " mt_ix %d, ch_ix %d, cnx_id %d, rbId %d\n", - mt_ix, ch_ix, currChannel->cnx_id, currChannel->rbId); - memcpy((char *)&(g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_addr), - (char *)&(g_enb_ral_obj[instanceP].pending_mt.ipv6_addr), 16); - LOG_D(RAL_ENB, " MT's address = %s\n", - eRAL_process_mt_addr_to_string(g_enb_ral_obj[instanceP].mt[mt_ix].ipv6_addr)); - - /* Save the pending data flow identifier into the list of active data flows */ - f_ix = eRAL_action_save_flow_id(instanceP, &g_enb_ral_obj[instanceP].pending_req_fid, currChannel->cnx_id); - - if (f_ix < 0) { - LOG_D(RAL_ENB, " No RB available - Deleting request data\n"); - eRAL_process_clean_pending_mt(instanceP); - return; - } - - /* Store resource parameters of the pending MT */ - for (dir = 0; dir < 2; dir++) { - currChannel->flowId[dir] = f_ix; - currChannel->classId[dir]= pendingChannel->classId[dir] ; - currChannel->resBitrate[dir] = pendingChannel->resBitrate[dir]; - currChannel->meanBitrate[dir] = pendingChannel->meanBitrate[dir]; - currChannel->bktDepth[dir] = pendingChannel->bktDepth[dir]; - currChannel->pkBitrate[dir] = pendingChannel->pkBitrate[dir]; - currChannel->MTU[dir] = pendingChannel->MTU[dir]; - LOG_D(RAL_ENB, " qos value : DIR %d, flowId %d, classId %d, resBitrate %.1f \n", - dir, currChannel->flowId[dir], currChannel->classId[dir], currChannel->resBitrate[dir]); - } - - /* Map Qos */ - mapping_result = eRAL_process_map_qos(instanceP, mt_ix, ch_ix); - - if (mapping_result) { -#ifdef RAL_DUMMY - rc = eRAL_NAS_send_rb_establish_request(mt_ix, ch_ix); -#endif -#ifdef RAL_REALTIME - // LG rc = RAL_process_NAS_message(IO_OBJ_RB, IO_CMD_ADD, mt_ix, ch_ix); -#endif - } - - if (rc < 0) { - /* Failed to send RB establishment request; release new RB data */ - eRAL_process_clean_channel(currChannel); - } else { - /* RB establishment request has been sent; release pending MT data */ - g_enb_ral_obj[instanceP].pending_req_flag = 0; - eRAL_process_clean_pending_mt(instanceP); - } -} - -/**************************************************************************** - ** Name: eRAL_process_clean_pending_mt() ** - ** Description: Deletes previously stored pending MT data. ** - ***************************************************************************/ -void eRAL_process_clean_pending_mt(ral_enb_instance_t instanceP) -{ - memset(g_enb_ral_obj[instanceP].pending_mt.ipv6_addr, 0 , 16); - eRAL_process_clean_channel(&g_enb_ral_obj[instanceP].pending_mt.radio_channel[0]); - - g_enb_ral_obj[instanceP].pending_mt_timer = -1; - LOG_D(RAL_ENB, " Pending MT data deleted\n"); -} - -/**************************************************************************** - ** MW Added ** - ***************************************************************************/ -//--------------------------------------------------------------------------- -void RAL_printInitStatus(ral_enb_instance_t instanceP) -{ - //--------------------------------------------------------------------------- - LOG_D(RAL_ENB, "Network status updated \n"); - LOG_D(RAL_ENB, "Mobile : %d, %d, %d, %d, %d, %d \n", - g_enb_ral_obj[instanceP].cell_id, - g_enb_ral_obj[instanceP].mt[0].ue_id, - g_enb_ral_obj[instanceP].mt[0].ipv6_l2id[0], - g_enb_ral_obj[instanceP].mt[0].ipv6_l2id[1], - g_enb_ral_obj[instanceP].mt[0].num_rbs , - g_enb_ral_obj[instanceP].mt[0].nas_state ); - LOG_D(RAL_ENB, "Default rb : %d, %d, %d, %d, %d, %d, %d \n", - g_enb_ral_obj[instanceP].mt[0].radio_channel[0].rbId , - g_enb_ral_obj[instanceP].mt[0].radio_channel[0].RadioQoSclass , - g_enb_ral_obj[instanceP].mt[0].radio_channel[0].cnx_id , - g_enb_ral_obj[instanceP].mt[0].radio_channel[0].dscpUL , - g_enb_ral_obj[instanceP].mt[0].radio_channel[0].dscpDL , - g_enb_ral_obj[instanceP].mt[0].radio_channel[0].nas_state , - g_enb_ral_obj[instanceP].mt[0].radio_channel[0].status ); - - LOG_D(RAL_ENB, "Number of connected MTs : %d\n\n", g_enb_ral_obj[instanceP].num_connected_mts); -} - -//--------------------------------------------------------------------------- -// poll for measures in NAS -void RAL_NAS_measures_polling(ral_enb_instance_t instanceP) -{ - //--------------------------------------------------------------------------- -#ifdef RAL_REALTIME - // LG RAL_process_NAS_message(IO_OBJ_MEAS, IO_CMD_LIST,0,0); -#endif -#ifdef RAL_DUMMY - eRAL_NAS_send_measure_request(); -#endif -} - -//--------------------------------------------------------------------------- -// Common function to report congestion -void RAL_NAS_report_congestion(ral_enb_instance_t instanceP, int ix) -{ - //--------------------------------------------------------------------------- - MIH_C_TRANSACTION_ID_T transaction_id; - MIH_C_LINK_TUPLE_ID_T link_identifier; - LIST(MIH_C_LINK_PARAM_RPT, LinkParametersReportList); - - LOG_D(RAL_ENB, "Congestion detected for UE%d, sending congestion notification to MIH User \n", ix); - transaction_id = MIH_C_get_new_transaction_id(); - link_identifier.link_id.link_type = MIH_C_WIRELESS_UMTS; - link_identifier.link_id.link_addr.choice = MIH_C_CHOICE_3GPP_3G_CELL_ID; - Bit_Buffer_t *plmn = new_BitBuffer_0(); - BitBuffer_wrap(plmn, (unsigned char*) &g_enb_ral_obj[instanceP].plmn_id, sizeof(g_enb_ral_obj[instanceP].plmn_id)); - MIH_C_PLMN_ID_decode(plmn, &link_identifier.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id); - free_BitBuffer(plmn); - link_identifier.link_id.link_addr._union._3gpp_3g_cell_id.cell_id = g_enb_ral_obj[instanceP].cell_id; - link_identifier.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - // - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type.choice = MIH_C_LINK_PARAM_TYPE_CHOICE_LTE; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type._union.link_param_lte = MIH_C_LINK_PARAM_LTE_L2_BUFFER_STATUS; - // LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type.choice = MIH_C_LINK_PARAM_TYPE_CHOICE_GEN; - // LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type._union.link_param_gen = MIH_C_LINK_PARAM_LTE_L2_BUFFER_STATUS; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - // LG obsolete rlcBufferOccupancy LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param._union.link_param_val = g_enb_ral_obj[instanceP].rlcBufferOccupancy[ix]; - - LinkParametersReportList_list.val[LinkParametersReportList_list.length].choice = MIH_C_LINK_PARAM_RPT_CHOICE_THRESHOLD; -#warning "TO DO" - //LinkParametersReportList_list.val[LinkParametersReportList_list.length]._union.threshold.threshold_val = g_enb_ral_obj[instanceP].congestion_threshold; - LinkParametersReportList_list.val[LinkParametersReportList_list.length]._union.threshold.threshold_xdir = MIH_C_ABOVE_THRESHOLD; - LinkParametersReportList_list.length = LinkParametersReportList_list.length + 1; - - // - eRAL_send_link_parameters_report_indication(instanceP, &transaction_id, &link_identifier, &LinkParametersReportList_list); -#warning "TO DO?" - //g_enb_ral_obj[instanceP].congestion_flag = RAL_TRUE; - -} -//--------------------------------------------------------------------------- -// Temp - Enter hard-coded measures in IAL -/*LGvoid RAL_NAS_measures_analyze(ral_enb_instance_t instanceP){ - //--------------------------------------------------------------------------- - MIH_C_TRANSACTION_ID_T transaction_id; - MIH_C_LINK_TUPLE_ID_T link_identifier; - LIST(MIH_C_LINK_PARAM_RPT, LinkParametersReportList); - int ix; - - LinkParametersReportList_list.length = 0; - - if (g_enb_ral_obj[instanceP].congestion_flag == RAL_FALSE){ - // Check congestion - for (ix=0; ix<g_enb_ral_obj[instanceP].num_UEs; ix++){ - if ((g_enb_ral_obj[instanceP].rlcBufferOccupancy[ix] > g_enb_ral_obj[instanceP].congestion_threshold)&& - ((g_enb_ral_obj[instanceP].mih_subscribe_req_event_list && MIH_C_BIT_LINK_PARAMETERS_REPORT )>0)){ - RAL_NAS_report_congestion(instanceP, ix); - break; - } - } - } else if (g_enb_ral_obj[instanceP].measures_triggered_flag == RAL_TRUE){ - // Measures should be reported to MIH user - LOG_D(RAL_ENB, "Sending traffic measures to MIH User \n"); - - transaction_id = MIH_C_get_new_transaction_id(); - link_identifier.link_id.link_type = MIH_C_WIRELESS_UMTS; - link_identifier.link_id.link_addr.choice = MIH_C_CHOICE_3GPP_3G_CELL_ID; - Bit_Buffer_t *plmn = new_BitBuffer_0(); - BitBuffer_wrap(plmn, (unsigned char*) g_enb_ral_obj[instanceP].plmn, DEFAULT_PLMN_SIZE); - MIH_C_PLMN_ID_decode(plmn, &link_identifier.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id); - free_BitBuffer(plmn); - link_identifier.link_id.link_addr._union._3gpp_3g_cell_id.cell_id = g_enb_ral_obj[instanceP].cell_id; - link_identifier.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - // - // send parameters !!! Value link_param_val must be in 0...65535 range - // UE0 scheduledPRB - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type.choice = MIH_C_LINK_PARAM_TYPE_CHOICE_LTE; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type._union.link_param_lte = MIH_C_LINK_PARAM_LTE_AVAILABLE_BW; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param._union.link_param_val = g_enb_ral_obj[instanceP].scheduledPRB[0]; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].choice = MIH_C_LINK_PARAM_RPT_CHOICE_NULL; - LinkParametersReportList_list.length = LinkParametersReportList_list.length + 1; - // UE0 totalDataVolume - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type.choice = MIH_C_LINK_PARAM_TYPE_CHOICE_LTE; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type._union.link_param_lte = MIH_C_LINK_PARAM_LTE_AVAILABLE_BW; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param._union.link_param_val = (g_enb_ral_obj[instanceP].totalDataVolume[0]/1000); - LinkParametersReportList_list.val[LinkParametersReportList_list.length].choice = MIH_C_LINK_PARAM_RPT_CHOICE_NULL; - LinkParametersReportList_list.length = LinkParametersReportList_list.length + 1; - // UE1 scheduledPRB - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type.choice = MIH_C_LINK_PARAM_TYPE_CHOICE_LTE; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type._union.link_param_lte = MIH_C_LINK_PARAM_LTE_AVAILABLE_BW; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param._union.link_param_val = g_enb_ral_obj[instanceP].scheduledPRB[1]; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].choice = MIH_C_LINK_PARAM_RPT_CHOICE_NULL; - LinkParametersReportList_list.length = LinkParametersReportList_list.length + 1; - // UE1 totalDataVolume - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type.choice = MIH_C_LINK_PARAM_TYPE_CHOICE_LTE; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type._union.link_param_lte = MIH_C_LINK_PARAM_LTE_AVAILABLE_BW; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param._union.link_param_val = (g_enb_ral_obj[instanceP].totalDataVolume[1]/1000); - LinkParametersReportList_list.val[LinkParametersReportList_list.length].choice = MIH_C_LINK_PARAM_RPT_CHOICE_NULL; - LinkParametersReportList_list.length = LinkParametersReportList_list.length + 1; - // totalNumPRBs - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type.choice = MIH_C_LINK_PARAM_TYPE_CHOICE_LTE; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type._union.link_param_lte = MIH_C_LINK_PARAM_LTE_AVAILABLE_BW; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param._union.link_param_val = g_enb_ral_obj[instanceP].totalNumPRBs; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].choice = MIH_C_LINK_PARAM_RPT_CHOICE_NULL; - LinkParametersReportList_list.length = LinkParametersReportList_list.length + 1; - // - eRAL_send_link_parameters_report_indication(instanceP, &transaction_id, &link_identifier, &LinkParametersReportList_list); - - } -} -*/ diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_rrc_msg.c b/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_rrc_msg.c deleted file mode 100755 index a0ec08121a..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_rrc_msg.c +++ /dev/null @@ -1,168 +0,0 @@ -/***************************************************************************** - * Eurecom OpenAirInterface 3 - * Copyright(c) 2012 Eurecom - * - * Source eRAL_subscribe.c - * - * Version 0.1 - * - * Date 11/27/2013 - * - * Product MIH RAL LTE - * - * Subsystem - * - * Authors Lionel Gauthier - * - * Description - * - *****************************************************************************/ -#define LTE_RAL_ENB -#define LTE_RAL_ENB_RRC_MSG_C -#include "lteRALenb.h" - -static int ueid2eui48(uint8_t *euiP, uint8_t* ue_idP) -{ - // inspired by linux-source-3.2.0/net/ipv6/addrconf.c - memcpy(euiP, ue_idP, 3); - memcpy(euiP + 5, ue_idP + 3, 3); - euiP[3] = 0xFF; - euiP[4] = 0xFE; - euiP[0] ^= 2; - return 0; -} - -//--------------------------------------------------------------------------------------------------------------------- -void eRAL_rx_rrc_ral_system_configuration_indication(instance_t instanceP, MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - module_id_t mod_id = instanceP; - g_enb_ral_obj[mod_id].plmn_id = RRC_RAL_SYSTEM_CONFIGURATION_IND(msg_pP).plmn_id; - g_enb_ral_obj[mod_id].cell_id = RRC_RAL_SYSTEM_CONFIGURATION_IND(msg_pP).cell_id; -} - -//--------------------------------------------------------------------------------------------------------------------- -void eRAL_rx_rrc_ral_connection_establishment_indication(instance_t instanceP, MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - MIH_C_LINK_TUPLE_ID_T link_tuple_id; -#ifdef USE_3GPP_ADDR_AS_LINK_ADDR - uint8_t ue_id_array[MIH_C_3GPP_ADDR_LENGTH]; - uint8_t mn_link_addr[MIH_C_3GPP_ADDR_LENGTH]; - uint64_t ue_id; //EUI-64 - int i; -#endif - module_id_t mod_id = instanceP; - - // The LINK_ID contains the MN LINK_ADDR - link_tuple_id.choice = MIH_C_LINK_TUPLE_ID_CHOICE_LINK_ADDR; - link_tuple_id.link_id.link_type = MIH_C_WIRELESS_LTE; -#ifdef USE_3GPP_ADDR_AS_LINK_ADDR - link_tuple_id.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - - memset(ue_id_array, 0, MIH_C_3GPP_ADDR_LENGTH); - ue_id = (uint64_t)RRC_RAL_CONNECTION_ESTABLISHMENT_IND(msg_pP).ue_id; - - for (i = 0; i < MIH_C_3GPP_ADDR_LENGTH; i++) { - ue_id_array[MIH_C_3GPP_ADDR_LENGTH-1-i] = (ue_id & 0x00000000000000FF); - ue_id = ue_id >> 8; - } - - ueid2eui48(mn_link_addr, ue_id_array); - MIH_C_3GPP_ADDR_set(&(link_tuple_id.link_id.link_addr._union._3gpp_addr), NULL, 8); - - // The optional LINK_ADDR contains a link address of PoA. - eRAL_MIH_C_3GPP_ADDR_load_3gpp_str_address(mod_id, &link_tuple_id._union.link_addr._union._3gpp_addr, (uint8_t*)ENB_DEFAULT_3GPP_ADDRESS); -#else -#warning TO DO UE ID - // preserve byte order of plmn id - memcpy(link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val, &g_enb_ral_obj[mod_id].plmn_id, 3); - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id = g_enb_ral_obj[mod_id].cell_id; - - LOG_D(RAL_ENB, "PLMN ID %d.%d.%d\n", - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[0], - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[1], - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[2]); - - LOG_D(RAL_ENB, "CELL ID %d\n", - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id); -#endif - - - eRAL_send_link_up_indication(instanceP, &g_enb_ral_obj[instanceP].transaction_id, - &link_tuple_id, - NULL, //MIH_C_LINK_ADDR_T *old_arP,(Optional) Old Access Router link address. - NULL, //MIH_C_LINK_ADDR_T *new_arP,(Optional) New Access Router link address. - NULL, //MIH_C_IP_RENEWAL_FLAG_T *flagP, (Optional) Indicates whether the MN needs to change IP Address in the new PoA. - NULL); //MIH_C_IP_MOB_MGMT_T *mobil_mngtP, (Optional) Indicates the type of Mobility Management Protocol supported by the new PoA. - - g_enb_ral_obj[instanceP].transaction_id ++; - -} -//--------------------------------------------------------------------------------------------------------------------- -void eRAL_rx_rrc_ral_connection_reestablishment_indication(instance_t instanceP, MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - // module_id_t mod_id = instanceP; -#warning "TO DO ral_rx_rrc_ral_connection_reestablishment_indication" -} -//--------------------------------------------------------------------------------------------------------------------- -void eRAL_rx_rrc_ral_connection_reconfiguration_indication(instance_t instanceP, MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - MIH_C_LINK_TUPLE_ID_T link_tuple_id; - uint8_t ue_id_array[MIH_C_3GPP_ADDR_LENGTH]; - uint8_t mn_link_addr[MIH_C_3GPP_ADDR_LENGTH]; - uint64_t ue_id; //EUI-64 - int i; - module_id_t mod_id = instanceP; - - // The LINK_ID contains the MN LINK_ADDR - link_tuple_id.link_id.link_type = MIH_C_WIRELESS_LTE; - link_tuple_id.link_id.link_addr.choice = MIH_C_CHOICE_3GPP_ADDR; - memset(ue_id_array, 0, MIH_C_3GPP_ADDR_LENGTH); -#warning "TO DO FIX UE_ID TYPE in rrc_ral_connection_establishment_ind_t" - ue_id = (uint64_t)RRC_RAL_CONNECTION_ESTABLISHMENT_IND(msg_pP).ue_id; - - for (i = 0; i < MIH_C_3GPP_ADDR_LENGTH; i++) { - ue_id_array[MIH_C_3GPP_ADDR_LENGTH-1-i] = (ue_id & 0x00000000000000FF); - ue_id = ue_id >> 8; - } - - ueid2eui48(mn_link_addr, ue_id_array); - MIH_C_3GPP_ADDR_set(&(link_tuple_id.link_id.link_addr._union._3gpp_addr), NULL, 8); - - //The optional LINK_ADDR may contains a link address of PoA. - link_tuple_id.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - - eRAL_send_link_up_indication(instanceP, &g_enb_ral_obj[instanceP].transaction_id, - &link_tuple_id, - NULL, //MIH_C_LINK_ADDR_T *old_arP,(Optional) Old Access Router link address. - NULL, //MIH_C_LINK_ADDR_T *new_arP,(Optional) New Access Router link address. - NULL, //MIH_C_IP_RENEWAL_FLAG_T *flagP, (Optional) Indicates whether the MN needs to change IP Address in the new PoA. - NULL); //MIH_C_IP_MOB_MGMT_T *mobil_mngtP, (Optional) Indicates the type of Mobility Management Protocol supported by the new PoA. - - g_enb_ral_obj[mod_id].transaction_id ++; - - -} -//--------------------------------------------------------------------------------------------------------------------- -void eRAL_rx_rrc_ral_measurement_report_indication(instance_t instanceP, MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - // module_id_t mod_id = instanceP; - -} -//--------------------------------------------------------------------------------------------------------------------- -void eRAL_rx_rrc_ral_connection_release_indication(instance_t instanceP, MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - // module_id_t mod_id = instanceP; - -} - - - - - - diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_subscribe.c b/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_subscribe.c deleted file mode 100755 index 5c06860f7d..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_subscribe.c +++ /dev/null @@ -1,113 +0,0 @@ -/***************************************************************************** - * Eurecom OpenAirInterface 3 - * Copyright(c) 2012 Eurecom - * - * Source lteRALenb_subscribe.c - * - * Version 0.1 - * - * Date 07/02/2012 - * - * Product MIH RAL LTE - * - * Subsystem - * - * Authors Michelle Wetterwald, Lionel Gauthier, Frederic Maurel - * - * Description - * - *****************************************************************************/ -#define LTE_RAL_ENB -#define LTE_RAL_ENB_SUBSCRIBE_C -#include "lteRALenb.h" - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRAL_subscribe_request() ** - ** ** - ** Description: Subscribes the MIH-F to receive specified link event ** - ** indications and sends Link Event Subscribe confirmation ** - ** to the MIH-F. ** - ** ** - ** Inputs: msgP: Pointer to the received MIH message ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -void eRAL_subscribe_request(ral_enb_instance_t instanceP, MIH_C_Message_Link_Event_Subscribe_request_t* msgP) -{ - MIH_C_STATUS_T status = MIH_C_STATUS_REJECTED; - - /* Check whether the action request is supported */ - if (g_enb_ral_obj[instanceP].mih_supported_link_command_list & MIH_C_BIT_LINK_EVENT_SUBSCRIBE) { - MIH_C_LINK_EVENT_LIST_T mih_subscribed_req_event_list; - - g_enb_ral_obj[instanceP].mih_subscribe_req_event_list |= (msgP->primitive.RequestedLinkEventList & g_enb_ral_obj[instanceP].mih_supported_link_event_list); - - mih_subscribed_req_event_list = g_enb_ral_obj[instanceP].mih_subscribe_req_event_list & msgP->primitive.RequestedLinkEventList; - - status = MIH_C_STATUS_SUCCESS; - - eRAL_send_event_subscribe_confirm(instanceP, &msgP->header.transaction_id, - &status, - &mih_subscribed_req_event_list); - } else { - eRAL_send_event_subscribe_confirm(instanceP, &msgP->header.transaction_id, - &status, - NULL); - } -} - -/**************************************************************************** - ** ** - ** Name: eRAL_unsubscribe_request() ** - ** ** - ** Description: Unsubscribes the MIH-F to receive specified link event ** - ** indications and sends Link Event Unsubscribe confirmation ** - ** to the MIH-F. ** - ** ** - ** Inputs: msgP: Pointer to the received MIH message ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -void eRAL_unsubscribe_request(ral_enb_instance_t instanceP, MIH_C_Message_Link_Event_Unsubscribe_request_t* msgP) -{ - MIH_C_STATUS_T status = MIH_C_STATUS_REJECTED; - - /* Check whether the action request is supported */ - if (g_enb_ral_obj[instanceP].mih_supported_link_command_list & MIH_C_BIT_LINK_EVENT_UNSUBSCRIBE) { - MIH_C_LINK_EVENT_LIST_T mih_unsubscribed_req_event_list; - MIH_C_LINK_EVENT_LIST_T saved_req_event_list; - - saved_req_event_list = g_enb_ral_obj[instanceP].mih_subscribe_req_event_list; - - g_enb_ral_obj[instanceP].mih_subscribe_req_event_list &= ~(msgP->primitive.RequestedLinkEventList & g_enb_ral_obj[instanceP].mih_supported_link_event_list); - mih_unsubscribed_req_event_list = g_enb_ral_obj[instanceP].mih_subscribe_req_event_list ^ saved_req_event_list; - - status = MIH_C_STATUS_SUCCESS; - - eRAL_send_event_unsubscribe_confirm(instanceP, &msgP->header.transaction_id, - &status, - &mih_unsubscribed_req_event_list); - } else { - eRAL_send_event_unsubscribe_confirm(instanceP, &msgP->header.transaction_id, - &status, - NULL); - } -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - diff --git a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_thresholds.c b/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_thresholds.c deleted file mode 100755 index 60603d039d..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_thresholds.c +++ /dev/null @@ -1,171 +0,0 @@ -/***************************************************************************** - * Eurecom OpenAirInterface 3 - * Copyright(c) 2012 Eurecom - * - * Source eRAL_thresholds.c - * - * Version 0.1 - * - * Date 07/03/2012 - * - * Product MIH RAL LTE - * - * Subsystem - * - * Authors Michelle Wetterwald, Lionel Gauthier, Frederic Maurel - * - * Description - * - *****************************************************************************/ -#define LTE_RAL_ENB -#define LTE_RAL_ENB_THRESHOLDS_C -#include <assert.h> -#include "lteRALenb.h" - - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRAL_configure_thresholds_request() ** - ** ** - ** Description: Forwards the Link_Configure_Thresholds.request message ** - ** to the RRC layer. ** - ** ** - ** Inputs: msgP: Pointer to the received message ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void eRAL_configure_thresholds_request(ral_enb_instance_t instanceP, MIH_C_Message_Link_Configure_Thresholds_request_t* msgP) -{ - unsigned int index; - unsigned int th_index; - rrc_ral_configure_threshold_req_t configure_threshold_req; - MessageDef *message_p; - - message_p = itti_alloc_new_message (TASK_RAL_ENB, RRC_RAL_CONFIGURE_THRESHOLD_REQ); - - memset(&configure_threshold_req, 0, sizeof(rrc_ral_configure_threshold_req_t)); - - // copy transaction id - configure_threshold_req.transaction_id = msgP->header.transaction_id; - - // configure_threshold_req.num_link_cfg_params = 0; // done - for (index = 0; index < msgP->primitive.LinkConfigureParameterList_list.length; index++) { - // copy link_param_type - configure_threshold_req.link_cfg_params[index].link_param_type.choice = msgP->primitive.LinkConfigureParameterList_list.val[index].link_param_type.choice; - - switch (configure_threshold_req.link_cfg_params[index].link_param_type.choice) { - case RAL_LINK_PARAM_TYPE_CHOICE_GEN: - memcpy(&configure_threshold_req.link_cfg_params[index].link_param_type._union.link_param_gen, - &msgP->primitive.LinkConfigureParameterList_list.val[index].link_param_type._union.link_param_gen, - sizeof(ral_link_param_gen_t)); - break; - - case RAL_LINK_PARAM_TYPE_CHOICE_QOS: - memcpy(&configure_threshold_req.link_cfg_params[index].link_param_type._union.link_param_qos, - &msgP->primitive.LinkConfigureParameterList_list.val[index].link_param_type._union.link_param_qos, - sizeof(ral_link_param_qos_t)); - break; - - case RAL_LINK_PARAM_TYPE_CHOICE_LTE: - memcpy(&configure_threshold_req.link_cfg_params[index].link_param_type._union.link_param_lte, - &msgP->primitive.LinkConfigureParameterList_list.val[index].link_param_type._union.link_param_lte, - sizeof(ral_link_param_lte_t)); - break; - - default: - assert(1==0); - } - - configure_threshold_req.num_link_cfg_params += 1; - - // copy choice - configure_threshold_req.link_cfg_params[index].union_choice = msgP->primitive.LinkConfigureParameterList_list.val[index].choice; - - // copy _union - switch (configure_threshold_req.link_cfg_params[index].union_choice) { - case RAL_LINK_CFG_PARAM_CHOICE_TIMER_NULL: - configure_threshold_req.link_cfg_params[index]._union.null_attr = 0; - break; - - case RAL_LINK_CFG_PARAM_CHOICE_TIMER: - configure_threshold_req.link_cfg_params[index]._union.timer_interval = msgP->primitive.LinkConfigureParameterList_list.val[index]._union.timer_interval; - - default: - assert(1==0); - } - - // copy th_action - configure_threshold_req.link_cfg_params[index].th_action = msgP->primitive.LinkConfigureParameterList_list.val[index].th_action; - - // configure_threshold_req.link_cfg_params[index].num_thresholds = 0; // done - for (th_index = 0; th_index < msgP->primitive.LinkConfigureParameterList_list.val[index].threshold_list.length; th_index++) { - configure_threshold_req.link_cfg_params[index].thresholds[th_index].threshold_val = msgP->primitive.LinkConfigureParameterList_list.val[index].threshold_list.val[th_index].threshold_val; - configure_threshold_req.link_cfg_params[index].thresholds[th_index].threshold_xdir = msgP->primitive.LinkConfigureParameterList_list.val[index].threshold_list.val[th_index].threshold_xdir; - configure_threshold_req.link_cfg_params[index].num_thresholds += 1; - } - } - - - memcpy (&message_p->ittiMsg, (void *) &configure_threshold_req, sizeof(rrc_ral_configure_threshold_req_t)); - itti_send_msg_to_task (TASK_RRC_ENB, instanceP, message_p); -} - -//--------------------------------------------------------------------------------------------------------------------- -void eRAL_rx_rrc_ral_configure_threshold_conf(instance_t instance, MessageDef *msg_p) -//--------------------------------------------------------------------------------------------------------------------- -{ - MIH_C_STATUS_T status; - // This parameter is not included if Status does not indicate “Success.†- MIH_C_LINK_CFG_STATUS_LIST_T link_cfg_status_list; - unsigned int i; - - status = RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_p).status; - - if (status == RAL_STATUS_SUCCESS) { - link_cfg_status_list.length = 0; - - for (i = 0; i < RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_p).num_link_cfg_params; i++) { - link_cfg_status_list.val[i].link_param_type.choice = RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_p).cfg_status[i].link_param_type.choice; - - switch (link_cfg_status_list.val[i].link_param_type.choice) { - case RAL_LINK_PARAM_TYPE_CHOICE_GEN: - memcpy(&link_cfg_status_list.val[i].link_param_type._union.link_param_gen, - &RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_p).cfg_status[i].link_param_type._union.link_param_gen, - sizeof(ral_link_param_gen_t)); - break; - - case RAL_LINK_PARAM_TYPE_CHOICE_QOS: - memcpy(&link_cfg_status_list.val[i].link_param_type._union.link_param_qos, - &RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_p).cfg_status[i].link_param_type._union.link_param_qos, - sizeof(ral_link_param_qos_t)); - break; - - case RAL_LINK_PARAM_TYPE_CHOICE_LTE: - memcpy(&link_cfg_status_list.val[i].link_param_type._union.link_param_lte, - &RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_p).cfg_status[i].link_param_type._union.link_param_lte, - sizeof(ral_link_param_lte_t)); - break; - - default: - assert(1==0); - } - - link_cfg_status_list.val[i].threshold.threshold_val = RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_p).cfg_status[i].threshold.threshold_val; - link_cfg_status_list.val[i].threshold.threshold_xdir = RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_p).cfg_status[i].threshold.threshold_xdir; - link_cfg_status_list.val[i].config_status = RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_p).cfg_status[i].config_status; - link_cfg_status_list.length += 1; - } - - eRAL_send_configure_thresholds_confirm(instance, &RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_p).transaction_id, &status, &link_cfg_status_list); - } else { - eRAL_send_configure_thresholds_confirm(instance, &RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_p).transaction_id, &status, NULL); - } -} diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue.h deleted file mode 100755 index a8b817afcf..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue.h +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef __LTE_RAL_UE_H__ -#define __LTE_RAL_UE_H__ - -#include "MIH_C.h" - -#include "openair_types.h" -#include "platform_constants.h" -#include "platform_types.h" - -#include "lteRALue_constants.h" -#include "lteRALue_variables.h" -#include "lteRALue_main.h" -#include "lteRALue_action.h" -#include "lteRALue_mih_msg.h" -#include "lteRALue_rrc_msg.h" -#include "lteRALue_parameters.h" -//#include "lteRALue_process.h" -#include "lteRALue_subscribe.h" -#include "lteRALue_thresholds.h" -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_action.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_action.h deleted file mode 100755 index 21db5afb18..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_action.h +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteralue_action.h - * \brief - * \author GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_UE_ACTION_H__ -#define __LTE_RAL_UE_ACTION_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_UE_ACTION_C -# define private_lteralue_action(x) x -# define protected_lteralue_action(x) x -# define public_lteralue_action(x) x -# else -# ifdef LTE_RAL_UE -# define private_lteralue_action(x) -# define protected_lteralue_action(x) extern x -# define public_lteralue_action(x) extern x -# else -# define private_lteralue_action(x) -# define protected_lteralue_action(x) -# define public_lteralue_action(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALue.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - -#endif // MIH_C_MEDIEVAL_EXTENSIONS -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ -protected_lteralue_action(void mRAL_action_request(ral_ue_instance_t instanceP, MIH_C_Message_Link_Action_request_t* messageP);) - - - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_constants.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_constants.h deleted file mode 100755 index 556e127fbf..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_constants.h +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALue_constants.h - * \brief Constants for LTE-RAL-UE - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#ifndef __LTERALUE_CONSTANTS_H__ -#define __LTERALUE_CONSTANTS_H__ -//----------------------------------------------------------------------------- -#define UE_DEFAULT_LOCAL_PORT_RAL "1234" -#define UE_DEFAULT_REMOTE_PORT_MIHF "1025" -#define UE_DEFAULT_IP_ADDRESS_MIHF "127.0.0.1" -#define UE_DEFAULT_IP_ADDRESS_RAL "127.0.0.1" -#define UE_DEFAULT_LINK_ID_RAL "ue_lte_link" -#define UE_DEFAULT_LINK_ADDRESS_RAL "060080149150" -#define UE_DEFAULT_MIHF_ID "mihf2_ue" -//#define UE_DEFAULT_3GPP_ADDRESS "0335060080149150" -#define UE_DEFAULT_3GPP_ADDRESS "0000000000000000" - -//----------------------------------------------------------------------------- -// Constants for scenario -#define PREDEFINED_MIH_PLMN_ID 503 -#define PREDEFINED_MIH_NETWORK_ID "eurecom" -#define PREDEFINED_MIH_NETAUX_ID "netaux" - -#define PREDEFINED_CHANNEL_ID 2 -#define PREDEFINED_CLASSES_SERVICE_SUPPORTED 2 -#define PREDEFINED_QUEUES_SUPPORTED 2 - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_main.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_main.h deleted file mode 100755 index 5e3a0d90a1..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_main.h +++ /dev/null @@ -1,187 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALue_main.h - * \brief This file defines the prototypes of the functions for lteRALue_main.c - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#ifndef __LTERALUE_MAIN_H__ -# define __LTERALUE_MAIN_H__ -//----------------------------------------------------------------------------- -# ifdef LTERALUE_MAIN_C -# define private_mrallte_main(x) x -# define protected_mrallte_main(x) x -# define public_mrallte_main(x) x -# else -# ifdef LTE_RAL_UE -# define private_mrallte_main(x) -# define protected_mrallte_main(x) extern x -# define public_mrallte_main(x) extern x -# else -# define private_mrallte_main(x) -# define protected_mrallte_main(x) -# define public_mrallte_main(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <netdb.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/time.h> -#include <ctype.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <getopt.h> -#include <libgen.h> -//----------------------------------------------------------------------------- -#include "lteRALue.h" -#include "commonDef.h" -#include "hashtable.h" -//#include "collection/hashtable/hashtable.h" - -public_mrallte_main(char* g_conf_ue_ral_listening_port;) -public_mrallte_main(char* g_conf_ue_ral_ip_address;) -public_mrallte_main(char* g_conf_ue_ral_link_id;) -public_mrallte_main(char* g_conf_ue_ral_link_address;) -public_mrallte_main(char* g_conf_ue_mihf_remote_port;) -public_mrallte_main(char* g_conf_ue_mihf_ip_address;) -public_mrallte_main(char* g_conf_ue_mihf_id;) - - -typedef int ral_ue_instance_t; - -typedef struct lte_ral_ue_object_s { - //------------------------ - // CONFIG PARAMETERS - //------------------------ - char* ral_listening_port; - char* ral_ip_address; - char* ral_link_address; - char* mihf_remote_port; - char* mihf_ip_address; - char* link_id; - char* mihf_id; - MIH_C_LINK_MIHCAP_FLAG_T link_mihcap_flag; // hardcoded parameters - MIH_C_NET_CAPS_T net_caps;// hardcoded parameters - - - // only to call ralu_verifyPendingConnection - uint8_t pending_req_flag; - - - // network parameters - uint16_t cell_id; - plmn_t plmn_id; - //uint16_t nas_state; - int state; - //uint32_t curr_signal_level; - uint32_t ipv6_l2id[2]; - //measures - uint8_t req_num_bs; - uint16_t req_cell_id[MAX_NUMBER_BS]; - uint32_t req_prov_id[MAX_NUMBER_BS]; - uint16_t req_order_index[MAX_NUMBER_BS]; - int num_measures; - uint16_t meas_cell_id[MAX_NUMBER_BS]; - uint32_t last_meas_level[MAX_NUMBER_BS]; - uint32_t integrated_meas_level[MAX_NUMBER_BS]; - uint32_t prev_integrated_meas_level[MAX_NUMBER_BS]; - uint32_t provider_id[MAX_NUMBER_BS]; - //Radio Bearers - uint16_t num_rb; - int num_class; - uint16_t rbId[RAL_MAX_RB]; - uint16_t QoSclass[RAL_MAX_RB]; - uint16_t dscp[RAL_MAX_RB]; - // statistics - //uint32_t rx_packets; - //uint32_t tx_packets; - //uint32_t rx_bytes; - //uint32_t tx_bytes; - //uint32_t rx_errors; - //uint32_t tx_errors; - //uint32_t rx_dropped; - //uint32_t tx_dropped; - //char buffer[800]; // For ioctl with NAS driver - - // MIH-INTERFACE data - // MIH-INTERFACE data - int mih_sock_desc; - - // Initialised, then read-only, supported actions - MIH_C_LINK_AC_TYPE_T mih_supported_action_list; - // action currently processed - MIH_C_LINK_AC_TYPE_T pending_req_action; - // actions requested by MIH-H - MIH_C_LINK_AC_TYPE_T req_action_list; - //MIH_C_STATUS_T pending_req_status; - MIH_C_LINK_AC_RESULT_T pending_req_ac_result; - //MIH_C_TRANSACTION_ID_T pending_req_transaction_id; - // set unset bits by MIH_C_Message_Link_Event_Subscribe_request MIH_C_Message_Link_Event_Unsubscribe_request - MIH_C_LINK_EVENT_LIST_T mih_subscribe_req_event_list; - // Initialised, then read-only - MIH_C_LINK_EVENT_LIST_T mih_supported_link_event_list; - // Initialised, then read-only - MIH_C_LINK_CMD_LIST_T mih_supported_link_command_list; - LIST(MIH_C_LINK_CFG_PARAM, mih_link_cfg_param_thresholds); - // to tell what are the configured thresholds in mih_link_cfg_param_thresholds_list - MIH_C_BOOLEAN_T active_mih_link_cfg_param_threshold[MIH_C_LINK_CFG_PARAM_LIST_LENGTH]; - MIH_C_BOOLEAN_T link_to_be_detected; - - - MIH_C_TRANSACTION_ID_T transaction_id; - -} lte_ral_ue_object_t; - - -/* RAL LTE internal data */ -protected_mrallte_main(lte_ral_ue_object_t g_ue_ral_obj[MAX_MODULES];) -private_mrallte_main(hash_table_t *g_ue_ral_fd2instance;); - -public_mrallte_main( void mRAL_init_default_values(void);) -public_mrallte_main( int mRAL_initialize(void);) -private_mrallte_main(void mRAL_process_file_descriptors(struct epoll_event *events, int nb_events);) -public_mrallte_main( void* mRAL_task(void *args_p);) - -#endif - - - - - - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_mih_execute.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_mih_execute.h deleted file mode 100755 index 4c4e3f78e7..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_mih_execute.h +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALue_mih_execute.h - * \brief This file defines the prototypes of the functions for lteRALue_mih_execute.c - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#ifndef __MRALLTE_MIH_EXECUTE_H__ -# define __MRALLTE_MIH_EXECUTE_H__ -//----------------------------------------------------------------------------- -# ifdef MRALLTE_MIH_EXECUTE_C -# define private_mRAL_mih_execute(x) x -# define protected_mRAL_mih_execute(x) x -# define public_mRAL_mih_execute(x) x -# else -# ifdef LTE_RAL_UE -# define private_mRAL_mih_execute(x) -# define protected_mRAL_mih_execute(x) extern x -# define public_mRAL_mih_execute(x) extern x -# else -# define private_mRAL_mih_execute(x) -# define protected_mRAL_mih_execute(x) -# define public_mRAL_mih_execute(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "lteRALue.h" - -//----------------------------------------------------------------------------- -protected_mRAL_mih_execute(MIH_C_LINK_ACTION_T g_link_action;) -//----------------------------------------------------------------------------- -protected_mRAL_mih_execute(void mRAL_action_request(MIH_C_Message_Link_Action_request_t* messageP);) -//----------------------------------------------------------------------------- -protected_mRAL_mih_execute(void mRAL_get_parameters_request(MIH_C_Message_Link_Get_Parameters_request_t* messageP);) -//----------------------------------------------------------------------------- -protected_mRAL_mih_execute(void mRAL_subscribe_request (MIH_C_Message_Link_Event_Subscribe_request_t* messageP);) -protected_mRAL_mih_execute(void mRAL_unsubscribe_request(MIH_C_Message_Link_Event_Unsubscribe_request_t* messageP);) -//----------------------------------------------------------------------------- -protected_mRAL_mih_execute(LIST(MIH_C_LINK_CFG_PARAM, g_link_cfg_param_thresholds);) -//----------------------------------------------------------------------------- -protected_mRAL_mih_execute(void mRAL_configure_thresholds_request(MIH_C_Message_Link_Configure_Thresholds_request_t* messageP);) -public_mRAL_mih_execute(void mRAL_check_thresholds_signal_strength(MIH_C_THRESHOLD_VAL_T new_valP, MIH_C_THRESHOLD_VAL_T old_valP);) -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_mih_msg.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_mih_msg.h deleted file mode 100755 index efd095823c..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_mih_msg.h +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALue_mih_msg.h - * \brief This file defines the prototypes of the functions for lteRALue_mih_msg.c - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#ifndef __LTERALUE_MIH_MSG_H__ -# define __LTERALUE_MIH_MSG_H__ -//----------------------------------------------------------------------------- -# ifdef LTERALUE_MIH_MSG_C -# define private_mRAL_mih_msg(x) x -# define protected_mRAL_mih_msg(x) x -# define public_mRAL_mih_msg(x) x -# else -# ifdef LTE_RAL_UE -# define private_mRAL_mih_msg(x) -# define protected_mRAL_mih_msg(x) extern x -# define public_mRAL_mih_msg(x) extern x -# else -# define private_mRAL_mih_msg(x) -# define protected_mRAL_mih_msg(x) -# define public_mRAL_mih_msg(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALue.h" - -#define MSG_CODEC_RECV_BUFFER_SIZE 16400 -#define MSG_CODEC_SEND_BUFFER_SIZE 16400 -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -public_mRAL_mih_msg( int mRAL_send_to_mih(ral_ue_instance_t instanceP, u_int8_t *bufferP, size_t lenP);) - -protected_mRAL_mih_msg( int mRAL_mihf_connect (ral_ue_instance_t instanceP);) - -protected_mRAL_mih_msg( void MIH_C_3GPP_ADDR_load_3gpp_str_address(ral_ue_instance_t instanceP, \ - MIH_C_3GPP_ADDR_T* _3gpp_addrP, \ - u_int8_t* strP);) - -protected_mRAL_mih_msg( void mRAL_send_link_register_indication (\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP);) - -protected_mRAL_mih_msg( void mRAL_send_link_detected_indication (\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_LINK_DET_INFO_T *link_detected_infoP);) - -protected_mRAL_mih_msg( void mRAL_send_link_up_indication(\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_LINK_TUPLE_ID_T *link_identifierP,\ - MIH_C_LINK_ADDR_T *old_access_routerP,\ - MIH_C_LINK_ADDR_T *new_access_routerP,\ - MIH_C_IP_RENEWAL_FLAG_T *ip_renewal_flagP,\ - MIH_C_IP_MOB_MGMT_T *mobility_management_supportP);) - -protected_mRAL_mih_msg( void mRAL_send_link_parameters_report_indication(\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_LINK_TUPLE_ID_T *link_identifierP,\ - MIH_C_LINK_PARAM_RPT_LIST_T *link_parameters_report_listP);) - -protected_mRAL_mih_msg( void mRAL_send_link_going_down_indication(\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_LINK_TUPLE_ID_T *link_identifierP,\ - MIH_C_UNSIGNED_INT2_T *time_intervalP,\ - MIH_C_LINK_GD_REASON_T *link_going_down_reasonP);) - -protected_mRAL_mih_msg( void mRAL_send_link_down_indication(\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_LINK_TUPLE_ID_T *link_identifierP,\ - MIH_C_LINK_ADDR_T *old_access_routerP,\ - MIH_C_LINK_DN_REASON_T *reason_codeP);) - -protected_mRAL_mih_msg( void mRAL_send_link_action_confirm(\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_SCAN_RSP_LIST_T *scan_response_setP,\ - MIH_C_LINK_AC_RESULT_T *link_action_resultP);) - -protected_mRAL_mih_msg( void mRAL_send_capability_discover_confirm(\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_EVENT_LIST_T *supported_link_event_listP,\ - MIH_C_LINK_CMD_LIST_T *supported_link_command_listP);) - -protected_mRAL_mih_msg( void mRAL_send_event_subscribe_confirm (\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_EVENT_LIST_T *response_link_event_listP);) - -protected_mRAL_mih_msg( void mRAL_send_event_unsubscribe_confirm (\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_EVENT_LIST_T *response_link_event_listP);) - -protected_mRAL_mih_msg( void mRAL_send_configure_thresholds_confirm(\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_CFG_STATUS_LIST_T *link_configure_status_listP);) - -protected_mRAL_mih_msg( void mRAL_send_get_parameters_confirm (\ - ral_ue_instance_t instanceP,\ - MIH_C_TRANSACTION_ID_T *transaction_idP,\ - MIH_C_STATUS_T *statusP,\ - MIH_C_LINK_PARAM_LIST_T *link_parameters_status_listP,\ - MIH_C_LINK_STATES_RSP_LIST_T *link_states_response_listP,\ - MIH_C_LINK_DESC_RSP_LIST_T *link_descriptors_response_listP);) - -private_mRAL_mih_msg( int mRAL_mih_link_msg_decode (\ - ral_ue_instance_t instanceP,\ - Bit_Buffer_t* bbP, MIH_C_Message_Wrapper_t *message_wrapperP);) - -protected_mRAL_mih_msg( int mRAL_mih_link_process_message (ral_ue_instance_t instanceP);) -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_parameters.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_parameters.h deleted file mode 100755 index e6e02a1b5f..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_parameters.h +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_parameters.h - * \brief - * \author GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_UE_PARAMETERS_H__ -#define __LTE_RAL_UE_PARAMETERS_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_UE_PARAMETERS_C -# define private_lteralue_parameters(x) x -# define protected_lteralue_parameters(x) x -# define public_lteralue_parameters(x) x -# else -# ifdef LTE_RAL_UE -# define private_lteralue_parameters(x) -# define protected_lteralue_parameters(x) extern x -# define public_lteralue_parameters(x) extern x -# else -# define private_lteralue_parameters(x) -# define protected_lteralue_parameters(x) -# define public_lteralue_parameters(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALue.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ -protected_lteralue_parameters(void mRAL_get_parameters_request(ral_ue_instance_t instanceP, MIH_C_Message_Link_Get_Parameters_request_t* messageP);) - - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_proto.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_proto.h deleted file mode 100755 index d793dcfa52..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_proto.h +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALue_proto.h - * \brief This file defines the prototypes of the common functions - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#ifndef __RAL_UE_LTE_PROTO_H__ -#define __RAL_UE_LTE_PROTO_H__ - -//lteRALue_ioctl.c -int RAL_ue_process_NAS_message(int ioctl_obj, int ioctl_cmd, int ioctl_cellid); - -//mRALuD_process.c -void IAL_ue_NAS_measures_init(void); -void IAL_ue_NAS_measures_update(int i); -void IAL_ue_integrate_measure(int measure, int i); -void rallte_ue_NAS_measures_polling(void); -int rallte_ue_NAS_corresponding_cell(int req_index); -void rallte_ue_verifyPendingConnection(void); - -void* ral_ue_task(void *args_p); - -#endif - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_rrc_msg.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_rrc_msg.h deleted file mode 100755 index cf0baf9614..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_rrc_msg.h +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_rrc_msg.h - * \brief - * \author GAUTHIER Lionel - * \date 2013 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_UE_RRC_MSG_H__ -#define __LTE_RAL_UE_RRC_MSG_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_UE_RRC_MSG_C -# define private_lteralue_rrc_msg(x) x -# define protected_lteralue_rrc_msg(x) x -# define public_lteralue_rrc_msg(x) x -# else -# ifdef LTE_RAL_UE -# define private_lteralue_rrc_msg(x) -# define protected_lteralue_rrc_msg(x) extern x -# define public_lteralue_rrc_msg(x) extern x -# else -# define private_lteralue_rrc_msg(x) -# define protected_lteralue_rrc_msg(x) -# define public_lteralue_rrc_msg(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALue.h" -#include "intertask_interface.h" - -protected_lteralue_rrc_msg(void mRAL_rx_rrc_ral_scan_confirm (instance_t instance, MessageDef *msg_p);) -protected_lteralue_rrc_msg(void mRAL_rx_rrc_ral_system_information_indication (instance_t instance, MessageDef *msg_p);) -protected_lteralue_rrc_msg(void mRAL_rx_rrc_ral_connection_establishment_indication (instance_t instance, MessageDef *msg_p);) -protected_lteralue_rrc_msg(void mRAL_rx_rrc_ral_connection_reestablishment_indication (instance_t instance, MessageDef *msg_p);) -protected_lteralue_rrc_msg(void mRAL_rx_rrc_ral_connection_reconfiguration_indication (instance_t instance, MessageDef *msg_p);) -protected_lteralue_rrc_msg(void mRAL_rx_rrc_ral_connection_release_indication (instance_t instance, MessageDef *msg_p);) - - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_subscribe.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_subscribe.h deleted file mode 100755 index 7fd8697eb7..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_subscribe.h +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_subscribe.h - * \brief - * \author GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_UE_SUBSCRIBE_H__ -#define __LTE_RAL_UE_SUBSCRIBE_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_UE_PROCESS_C -# define private_lteralue_subscribe(x) x -# define protected_lteralue_subscribe(x) x -# define public_lteralue_subscribe(x) x -# else -# ifdef LTE_RAL_UE -# define private_lteralue_subscribe(x) -# define protected_lteralue_subscribe(x) extern x -# define public_lteralue_subscribe(x) extern x -# else -# define private_lteralue_subscribe(x) -# define protected_lteralue_subscribe(x) -# define public_lteralue_subscribe(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALue.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ -protected_lteralue_subscribe(void mRAL_subscribe_request (ral_ue_instance_t instanceP, MIH_C_Message_Link_Event_Subscribe_request_t* msgP);) -protected_lteralue_subscribe(void mRAL_unsubscribe_request(ral_ue_instance_t instanceP, MIH_C_Message_Link_Event_Unsubscribe_request_t* msgP);) - - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_thresholds.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_thresholds.h deleted file mode 100755 index 605558d808..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_thresholds.h +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALenb_thresholds.h - * \brief - * \author GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __LTE_RAL_UE_THRESHOLDS_H__ -#define __LTE_RAL_UE_THRESHOLDS_H__ -//----------------------------------------------------------------------------- -# ifdef LTE_RAL_UE_PROCESS_C -# define private_lteralue_thresholds(x) x -# define protected_lteralue_thresholds(x) x -# define public_lteralue_thresholds(x) x -# else -# ifdef LTE_RAL_UE -# define private_lteralue_thresholds(x) -# define protected_lteralue_thresholds(x) extern x -# define public_lteralue_thresholds(x) extern x -# else -# define private_lteralue_thresholds(x) -# define protected_lteralue_thresholds(x) -# define public_lteralue_thresholds(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include "lteRALue.h" -#include "intertask_interface.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -//LIST(MIH_C_LINK_CFG_PARAM, g_link_cfg_param_thresholds); - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -protected_lteralue_thresholds(void mRAL_configure_thresholds_request (ral_ue_instance_t instanceP, MIH_C_Message_Link_Configure_Thresholds_request_t* messageP);) -protected_lteralue_thresholds(void mRAL_rx_rrc_ral_configure_threshold_conf (ral_ue_instance_t instance, MessageDef *msg_p);) -protected_lteralue_thresholds(void mRAL_rx_rrc_ral_measurement_report_indication (ral_ue_instance_t instance, MessageDef *msg_p);) - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_variables.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_variables.h deleted file mode 100755 index f22dab76c8..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/lteRALue_variables.h +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file lteRALue_mih_msg.h - * \brief This file defines the data structures and LTE-RAL-UE protocol parameters - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#ifndef __LTERALUE_VARIABLES_H__ -#define __LTERALUE_VARIABLES_H__ -//------------------------------------------------------------------- - -#include "lteRALue.h" - -/*************************************************************************** - CONSTANTS - ***************************************************************************/ -//#define RAL_DUMMY -#define RAL_REALTIME -//#define MRALU_SIMU_LINKDOWN -//#define DEBUG_MRALU_MEASURES -//#define UPDATE - - -#define RALU_MT_EVENT_MAP MIH_EVENT_Link_AdvertisementIndication + MIH_EVENT_Link_Parameters_ReportIndication + MIH_EVENT_Link_UpIndication + MIH_EVENT_Link_DownIndication - -#define MIHLink_MAX_LENGTH 500 -#define MAX_NUMBER_BS 3 /* Max number of base stations */ -#define CONF_UNKNOWN_CELL_ID 0 -#define UMTS_INTF_NAME "graal0" - -//Attachment status -#define UNKNOWN 9 -#define CONNECTED 1 -#define DISCONNECTED 0 -//max number RB supported (27 in Spec) -#define RAL_MAX_RB 5 - -// constant for integrating measures according to the formula -// y[n] = (1-LAMBDA)*u[n-1] + LAMBDA*u[n] -#define LAMBDA 8 -#define MEAS_MAX_RSSI 110 - -/*************************************************************************** - VARIABLES - ***************************************************************************/ -//struct ral_lte_priv { - -//}; - -//----------------------------------------------------------------------------- -//extern struct ral_lte_priv *ralpriv; - -#endif - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/nas_ue_ioctl.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/nas_ue_ioctl.h deleted file mode 100755 index 01bdf75fc9..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/nas_ue_ioctl.h +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file nas_ue_ioctl.h - * \brief This file defines the constants for triggering the ioctl interface - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#ifndef _IAL_IOCTL_H -#define _IAL_IOCTL_H - -#include <sys/ioctl.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <net/if.h> - -#include <netinet/in.h> - -// Temp constants = arguments gioctl -//arg[0] -#define IO_OBJ_STATS 0 -#define IO_OBJ_CNX 1 -#define IO_OBJ_RB 2 -#define IO_OBJ_MEAS 3 -#define IO_OBJ_IMEI 4 -//arg[1] -#define IO_CMD_ADD 0 -#define IO_CMD_DEL 1 -#define IO_CMD_LIST 2 - - - -//LGextern int inet_pton(int af, const char *src, void *dst); -//LGextern char *inet_ntop(int af, const void *src, char *dst, size_t sise); - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/rrc_d_types.h b/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/rrc_d_types.h deleted file mode 100755 index 20f896a04a..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/INCLUDE/rrc_d_types.h +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file rrc_d_types.h - * \brief This file defines shortcuts to main unsigned types (part of LTE_RAL_UE - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#ifndef __RRC_DTYPES_H__ -#define __RRC_DTYPES_H__ - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; - - -#endif diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/link_sap.conf b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/link_sap.conf deleted file mode 100755 index 4ca476fbbe..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/link_sap.conf +++ /dev/null @@ -1,47 +0,0 @@ -#=============================================================================== -# Brief : Link SAP configuration file -# Authors : Carlos Guimaraes <cguimaraes@av.it.pt> -# Bruno Santos <bsantos@av.it.pt> -#------------------------------------------------------------------------------- -# ODTONE - Open Dot Twenty One -# -# Copyright (C) 2009-2012 Universidade Aveiro -# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -# -# This software is distributed under a license. The full license -# agreement can be found in the file LICENSE in this distribution. -# This software may not be copied, modified, sold or distributed -# other than expressed in the named license agreement. -# -# This software is distributed without any warranty. -#=============================================================================== - -[link] -## -## Link SAP identifier -## -id=link1 - -## -## Link SAP listening -## -port = 1235 - -## -## Link SAP interface technology -## -tec = LTE - -## -## Link SAP interface address -## -link_addr = 00:11:22:33:44:55 - -## -## Comma separated list of the Link SAP supported events -## -event_list = link_detected, link_up, link_down, link_parameters_report, link_going_down, link_handover_imminent, link_handover_complete - -[mihf] -ip=127.0.0.1 -local_port=1025 diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/lte_user.conf b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/lte_user.conf deleted file mode 100755 index 4e14bcf4a9..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/lte_user.conf +++ /dev/null @@ -1,40 +0,0 @@ -#=============================================================================== -# Brief : MIH-User configuration file -# Authors : Carlos Guimaraes <cguimaraes@av.it.pt> -# Bruno Santos <bsantos@av.it.pt> -#------------------------------------------------------------------------------- -# ODTONE - Open Dot Twenty One -# -# Copyright (C) 2009-2012 Universidade Aveiro -# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -# -# This software is distributed under a license. The full license -# agreement can be found in the file LICENSE in this distribution. -# This software may not be copied, modified, sold or distributed -# other than expressed in the named license agreement. -# -# This software is distributed without any warranty. -#=============================================================================== - -## -## User id -## -[user] -id = user - -## -## Commands supported by the MIH-User -## -commands = mih_link_get_parameters, mih_link_configure_thresholds, mih_link_actions, mih_net_ho_candidate_query, mih_net_ho_commit, mih_n2n_ho_query_resources, mih_n2n_ho_commit, mih_n2n_ho_complete, mih_mn_ho_candidate_query, mih_mn_ho_commit, mih_mn_ho_complete - -## -## Port used for communication with MIHF -## -[conf] -port = 1234 - -## -## MIHF configuration. For the default demonstration leave as is. -## -[mihf] -local_port = 1025 diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/odtone.conf b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/odtone.conf deleted file mode 100755 index fd3ef9d859..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/dist/odtone.conf +++ /dev/null @@ -1,71 +0,0 @@ -#=============================================================================== -# Brief : MIHF configuration file -# Authors : Carlos Guimaraes <cguimaraes@av.it.pt> -#------------------------------------------------------------------------------- -# ODTONE - Open Dot Twenty One -# -# Copyright (C) 2009-2012 Universidade Aveiro -# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -# -# This software is distributed under a license. The full license -# agreement can be found in the file LICENSE in this distribution. -# This software may not be copied, modified, sold or distributed -# other than expressed in the named license agreement. -# -# This software is distributed without any warranty. -#=============================================================================== - -[mihf] -## -## This mihf's id -## -## Usage: id = <MIHF ID> -## -id = mihf1 - -## -## Port on localhost that MIH Users and MIH Link SAPs connect to. -## -## Usage: local_port = <port> -## -local_port = 1025 - -## -## Port to which remote peer MIHF connect to -## -## Usage: remote_port = <port> -## -#remote_port = 4551 - -## -## Comma seperated list of remote MIHF's -## -## If you want to test remote MIHF communication add an entry here -## with the IP address of the remote MIHF. -## -## Usage: peers = <mihf id> <ip> <port>, ... -## -#peers = mihf2 0.0.0.0 4552 - -## -## Comma separated list of local MIH User SAPs id's and ports -## -## Usage: users = <user sap id> <port> [<supported commands> <supported queries>], ... -## Note: If no command is specified, the MIHF will assume that the MIH-User -## supports all MIH_***_HO_*** commands and the MIH_Get_Information -## Note: If no query is specified, the MIHF will assume that the MIH-User does -## not support the MIH_Get_Information command. -## -users = user 1234 - -## -## Comma separated list of local MIH Link SAPs id's and ports. -## -## Usage: links = <link sap id> <port> <techonoly type> <interface> [<supported events list> <supported commands list>], ... -## -#links = wifi 1235 802_11 00:11:22:33:44:55, lte 1234 LTE 00:11:22 5 - -## -## Comma separated list of the MIHF's transport protocol -## -transport = udp diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/Jamfile b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/Jamfile deleted file mode 100755 index 36011a7356..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/Jamfile +++ /dev/null @@ -1,34 +0,0 @@ -#=============================================================================== -# Brief : MIH-User SAP Application Sample Project Build -# Authors : Carlos Guimaraes <cguimaraes@av.it.pt> -# Bruno Santos <bsantos@av.it.pt> -#------------------------------------------------------------------------------- -# ODTONE - Open Dot Twenty One -# -# Copyright (C) 2009-2012 Universidade Aveiro -# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -# -# This software is distributed under a license. The full license -# agreement can be found in the file LICENSE in this distribution. -# This software may not be copied, modified, sold or distributed -# other than expressed in the named license agreement. -# -# This software is distributed without any warranty. -#=============================================================================== - - -install install - : ue_lte_user - ue_lte_user.conf - : <location>../../dist - ; - -project ue_lte_user - ; - -exe ue_lte_user - : ue_lte_user.cpp - ../../lib/odtone//odtone - /boost//program_options - ; - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/README.txt b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/README.txt deleted file mode 100755 index 2e951b5bec..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/README.txt +++ /dev/null @@ -1,11 +0,0 @@ -FILES TO BE USED: -Jamfile -ue_lte_user.conf -ue_lte_user.cpp -README.txt - -FILES OBSOLETES: -lte_user.conf -mih_usr.cpp - - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/lte_user.conf b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/lte_user.conf deleted file mode 100755 index ab40db1085..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/lte_user.conf +++ /dev/null @@ -1,42 +0,0 @@ -#=============================================================================== -# Brief : MIH-User configuration file -# Authors : Carlos Guimaraes <cguimaraes@av.it.pt> -# Bruno Santos <bsantos@av.it.pt> -#------------------------------------------------------------------------------- -# ODTONE - Open Dot Twenty One -# -# Copyright (C) 2009-2012 Universidade Aveiro -# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -# -# This software is distributed under a license. The full license -# agreement can be found in the file LICENSE in this distribution. -# This software may not be copied, modified, sold or distributed -# other than expressed in the named license agreement. -# -# This software is distributed without any warranty. -#=============================================================================== - -## -## User id -## -[user] -id = user_ue - -## -## Commands supported by the MIH-User -## -commands = mih_link_get_parameters, mih_link_configure_thresholds, mih_link_actions, mih_net_ho_candidate_query, mih_net_ho_commit, mih_n2n_ho_query_resources, mih_n2n_ho_commit, mih_n2n_ho_complete, mih_mn_ho_candidate_query, mih_mn_ho_commit, mih_mn_ho_complete - -## -## Port used for communication with MIHF -## -[conf] -port = 1235 - -## -## MIHF configuration. For the default demonstration leave as is. -## -[mihf] -local_port = 1025 - - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/mih_usr.cpp b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/mih_usr.cpp deleted file mode 100755 index 89722b7a1b..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/mih_usr.cpp +++ /dev/null @@ -1,1509 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include <odtone/base.hpp> -#include <odtone/debug.hpp> -#include <odtone/logger.hpp> -#include <odtone/mih/request.hpp> -#include <odtone/mih/response.hpp> -#include <odtone/mih/indication.hpp> -#include <odtone/mih/confirm.hpp> -#include <odtone/mih/tlv_types.hpp> -#include <odtone/sap/user.hpp> - -#include <boost/utility.hpp> -#include <boost/bind.hpp> -#include <boost/tokenizer.hpp> -#include <boost/foreach.hpp> - -#include <iostream> - -#define THRESHOLD_HIGH_VAL 90 -#define THRESHOLD_LOW_VAL 15 -//#define TEST_DEACTIVATION -#define NUM_ACT_DEACT 3 - - -/////////////////////////////////////////////////////////////////////////////// -// The scenario coded in this MIH-USER is the following (with mRALlteDummy and NASUEDummy executables) -// +--------+ +-----+ -// |MIH_USER| |MIH-F| -// +---+----+ +--+--+ -// |---------- User_Register.indication ---------------->| (supported_commands) Handler next msg=user_reg_handler -// | | -// |---------- Capability_Discover.request ------------->| Handler next msg=receive_MIH_Capability_Discover_confirm -// |<--------- Capability_Discover.confirm --------------| (success) -// | | -// |---------- Event_Subscribe.request ----------------->| Handler next msg=receive_MIH_Event_Subscribe_response -// |<--------- Event_Subscribe.response -----------------| (success) -// | | -// |---------- Configure_Thresholds.request ------------>| (High signal strength value) Handler next msg=event_handler -// |<--------- Configure_Thresholds.confirm -------------| link_get_parameters_request = 1 -// | | -// |---------- Link_Get_Parameters.request ------------->| Handler next msg=event_handler (link_get_parameters_request) -// |<--------- Link_Get_Parameters.confirm --------------| (success) -// | . | -// | . | -// | . | -// |<--------- Link_Detected.indication -----------------| link_action_request = 0 -// |---------- Link_Actions.request -------------------->| (power-up+scan) Handler next msg=event_handler -// |<--------- Link_Actions.confirm ---------------------| (success) -// |---------- Link_Actions.request -------------------->| (power-up) Handler next msg=event_handler -// |<--------- Link_Actions.confirm ---------------------| (success) -// | . | -// | . | -// |<--------- Link_Parameters_Report.indication --------| (Threshold crossed) Now (signal strength will decrease) -// | | -// |---------- Configure_Thresholds.request ------------>| (Low signal strength value) Handler next msg=event_handler -// |<--------- Configure_Thresholds.confirm -------------| (success) -// | . | -// | . | -// |<--------- Link_Parameters_Report.indication --------| (Threshold crossed) -// |---------- Link_Actions.request -------------------->| (power-down) Handler next msg=event_handler -// | . | -// |<--------- Link_Actions.confirm ---------------------| (success) -// | | -// | | -/////////////////////////////////////////////////////////////////////////////// - -static const char* const kConf_MIH_Commands = "user.commands"; -/////////////////////////////////////////////////////////////////////////////// - -namespace po = boost::program_options; - -using odtone::uint; -using odtone::ushort; -using odtone::sint8; - -odtone::logger log_("[mih_usr]", std::cout); - -/////////////////////////////////////////////////////////////////////////////// -void __trim(odtone::mih::octet_string &str, const char chr) -{ - str.erase(std::remove(str.begin(), str.end(), chr), str.end()); -} - -//----------------------------------------------------------------------------- -template <class T> std::string StringOf(T object) { -//----------------------------------------------------------------------------- - std::ostringstream os; - os << object; - return(os.str()); -} -//----------------------------------------------------------------------------- -std::string getTimeStamp4Log() -//----------------------------------------------------------------------------- -{ - std::stringstream ss (std::stringstream::in | std::stringstream::out); - struct timespec time_spec; - unsigned int time_now_micros; - unsigned int time_now_s; - clock_gettime (CLOCK_REALTIME, &time_spec); - time_now_s = (unsigned int) time_spec.tv_sec % 3600; - time_now_micros = (unsigned int) time_spec.tv_nsec/1000; - //time_now_s = 110; - //time_now_micros = 22; - ss << time_now_s << ':' << time_now_micros; - return ss.str(); -} -//----------------------------------------------------------------------------- -std::string status2string(odtone::mih::status statusP){ -//----------------------------------------------------------------------------- - switch (statusP.get()) { - case odtone::mih::status_success: return "SUCCESS";break; - case odtone::mih::status_failure: return "UNSPECIFIED_FAILURE";break; - case odtone::mih::status_rejected: return "REJECTED";break; - case odtone::mih::status_authorization_failure: return "AUTHORIZATION_FAILURE";break; - case odtone::mih::status_network_error: return "NETWORK_ERROR";break; - default: return "UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string link_down_reason2string(odtone::mih::link_dn_reason reasonP){ -//----------------------------------------------------------------------------- - switch (reasonP.get()) { - case odtone::mih::link_dn_reason_explicit_disconnect: return "DN_REASON_EXPLICIT_DISCONNECT";break; - case odtone::mih::link_dn_reason_packet_timeout: return "DN_REASON_PACKET_TIMEOUT";break; - case odtone::mih::link_dn_reason_no_resource: return "DN_REASON_NO_RESOURCE";break; - case odtone::mih::link_dn_reason_no_broadcast: return "DN_REASON_NO_BROADCAST";break; - case odtone::mih::link_dn_reason_authentication_failure: return "DN_REASON_AUTHENTICATION_FAILURE";break; - case odtone::mih::link_dn_reason_billing_failure: return "DN_REASON_BILLING_FAILURE";break; - default: return "DN_REASON_UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string link_going_down_reason2string(odtone::mih::link_gd_reason reasonP){ -//----------------------------------------------------------------------------- - switch (reasonP.get()) { - case odtone::mih::link_gd_reason_explicit_disconnect: return "GD_REASON_EXPLICIT_DISCONNECT";break; - case odtone::mih::link_gd_reason_link_parameter_degrading: return "GD_REASON_PARAMETER_DEGRADING";break; - case odtone::mih::link_gd_reason_low_power: return "GD_REASON_LOW_POWER";break; - case odtone::mih::link_gd_reason_no_resource: return "GD_REASON_NO_RESOURCE";break; - default: return "GD_REASON_UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string evt2string(odtone::mih::mih_evt_list evtP){ -//----------------------------------------------------------------------------- - std::string s; - if(evtP.get(odtone::mih::mih_evt_link_detected)) s = std::string("DETECTED, "); - if(evtP.get(odtone::mih::mih_evt_link_up)) s += "UP, "; - if(evtP.get(odtone::mih::mih_evt_link_down)) s += "DOWN, "; - if(evtP.get(odtone::mih::mih_evt_link_parameters_report)) s += "PARAMETERS_REPORT, "; - if(evtP.get(odtone::mih::mih_evt_link_going_down)) s += "GOING_DOWN, "; - if(evtP.get(odtone::mih::mih_evt_link_handover_imminent)) s += "HANDOVER_IMMINENT, "; - if(evtP.get(odtone::mih::mih_evt_link_handover_complete)) s += "HANDOVER_COMPLETE, "; - if(evtP.get(odtone::mih::mih_evt_link_pdu_transmit_status)) s += "PDU_TRANSMIT_STATUS, "; - return s; -} -//----------------------------------------------------------------------------- -std::string link_id2string(odtone::mih::link_id linkP){ -//----------------------------------------------------------------------------- - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - std::string s; - - switch (linkP.type.get()) { - case odtone::mih::link_type_gsm: - s="GSM"; - break; - case odtone::mih::link_type_gprs: - s="GPRS"; - break; - case odtone::mih::link_type_edge: - s="EDGE"; - break; - case odtone::mih::link_type_ethernet: - s="Ethernet"; - break; - case odtone::mih::link_type_wireless_other: - s="Other"; - break; - case odtone::mih::link_type_802_11: - s="IEEE 802.11"; - break; - case odtone::mih::link_type_lte: - s="LTE"; - // address copied from UMTS - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(linkP.addr); - s = s + std::string(local_l2_3gpp_addr.value); - break; - case odtone::mih::link_type_cdma2000: - s="CDMA-2000"; - break; - case odtone::mih::link_type_umts: - s="UMTS:"; - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(linkP.addr); - /*index = 0; - for(iter=0; iter < local_l2_3gpp_addr.value.length(); iter++) { - index += sprintf(&buf[index],"-%hhx-", local_l2_3gpp_addr.value[iter]); - }*/ - s = s + std::string(local_l2_3gpp_addr.value); - break; - case odtone::mih::link_type_cdma2000_hrpd: - s="CDMA-2000-HRPD"; - break; - case odtone::mih::link_type_802_16: - s="IEEE 802.16"; - break; - case odtone::mih::link_type_802_20: - s="IEEE 802.20"; - break; - case odtone::mih::link_type_802_22: - s="IEEE 802.22"; - break; - } - return s; -} -//----------------------------------------------------------------------------- -std::string link_tupple_id2string(odtone::mih::link_tuple_id link_tuppleP){ -//----------------------------------------------------------------------------- - std::string s; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - switch (link_tuppleP.type.get()) { - case odtone::mih::link_type_gsm: - s="GSM"; - break; - case odtone::mih::link_type_gprs: - s="GPRS"; - break; - case odtone::mih::link_type_edge: - s="EDGE"; - break; - case odtone::mih::link_type_ethernet: - s="Ethernet"; - break; - case odtone::mih::link_type_wireless_other: - s="Other"; - break; - case odtone::mih::link_type_802_11: - s="IEEE 802.11"; - break; - case odtone::mih::link_type_lte: - s="LTE"; - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link_tuppleP.addr); - s = s + std::string(local_l2_3gpp_addr.value); - break; - case odtone::mih::link_type_cdma2000: - s="CDMA-2000"; - break; - case odtone::mih::link_type_umts: - s="UMTS:"; - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link_tuppleP.addr); - /*index = 0; - for(iter=0; iter < local_l2_3gpp_addr.value.length(); iter++) { - index += sprintf(&buf[index],"-%hhx-", local_l2_3gpp_addr.value[iter]); - }*/ - break; - case odtone::mih::link_type_cdma2000_hrpd: - s="CDMA-2000-HRPD"; - break; - case odtone::mih::link_type_802_16: - s="IEEE 802.16"; - break; - case odtone::mih::link_type_802_20: - s="IEEE 802.20"; - break; - case odtone::mih::link_type_802_22: - s="IEEE 802.22"; - break; - } - return s; -} -//----------------------------------------------------------------------------- -std::string link_actions_req2string(odtone::mih::link_action_req link_act_reqP) { -//----------------------------------------------------------------------------- - std::string s; - - s = link_id2string(link_act_reqP.id); - - if(link_act_reqP.action.type == odtone::mih::link_ac_type_none) s += ", AC_TYPE_NONE"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_disconnect) s += ", AC_TYPE_DISCONNECT"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_low_power) s += ", AC_TYPE_LOW_POWER"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_down) s += ", AC_TYPE_POWER_DOWN"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_up) s += ", AC_TYPE_POWER_UP"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_flow_attr) s += ", AC_TYPE_FLOW_ATTR"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_activate_resources) s += ", AC_TYPE_ACTIVATE_RESOURCES"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_deactivate_resources) s += ", AC_TYPE_DEACTIVATE_RESOURCES"; - - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_data_fwd_req)) s += ", AC_ATTR_DATA_FWD_REQ"; - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_scan)) s += ", AC_ATTR_SCAN"; - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_res_retain)) s += ", AC_ATTR_RES_RETAIN"; - - s += ", " + StringOf(link_act_reqP.ex_time) + " ms"; - return s; -} -//----------------------------------------------------------------------------- -std::string net_type_addr_list2string(boost::optional<odtone::mih::net_type_addr_list> ntalP) { -//----------------------------------------------------------------------------- - std::string s; - odtone::mih::link_id link_id; - for (odtone::mih::net_type_addr_list::iterator i = ntalP->begin(); i != ntalP->end(); ++i) - { - link_id.addr = boost::get<odtone::mih::l2_3gpp_addr>(i->addr); - link_id.type = boost::get<odtone::mih::link_type>(i->nettype.link); - s += link_id2string(link_id); - } - return s; -} - - -/** - * Parse supported commands. - * - * @param cfg Configuration options. - * @return A bitmap mapping the supported commands. - */ -boost::optional<odtone::mih::mih_cmd_list> parse_supported_commands(const odtone::mih::config &cfg) -{ - using namespace boost; - - odtone::mih::mih_cmd_list commands; - bool has_cmd = false; - - std::map<std::string, odtone::mih::mih_cmd_list_enum> enum_map; - enum_map["mih_link_get_parameters"] = odtone::mih::mih_cmd_link_get_parameters; - enum_map["mih_link_configure_thresholds"] = odtone::mih::mih_cmd_link_configure_thresholds; - enum_map["mih_link_actions"] = odtone::mih::mih_cmd_link_actions; - enum_map["mih_net_ho_candidate_query"] = odtone::mih::mih_cmd_net_ho_candidate_query; - enum_map["mih_net_ho_commit"] = odtone::mih::mih_cmd_net_ho_commit; - enum_map["mih_n2n_ho_query_resources"] = odtone::mih::mih_cmd_n2n_ho_query_resources; - enum_map["mih_n2n_ho_commit"] = odtone::mih::mih_cmd_n2n_ho_commit; - enum_map["mih_n2n_ho_complete"] = odtone::mih::mih_cmd_n2n_ho_complete; - enum_map["mih_mn_ho_candidate_query"] = odtone::mih::mih_cmd_mn_ho_candidate_query; - enum_map["mih_mn_ho_commit"] = odtone::mih::mih_cmd_mn_ho_commit; - enum_map["mih_mn_ho_complete"] = odtone::mih::mih_cmd_mn_ho_complete; - - std::string tmp = cfg.get<std::string>(kConf_MIH_Commands); - __trim(tmp, ' '); - - char_separator<char> sep1(","); - tokenizer< char_separator<char> > list_tokens(tmp, sep1); - - BOOST_FOREACH(std::string str, list_tokens) { - if(enum_map.find(str) != enum_map.end()) { - commands.set((odtone::mih::mih_cmd_list_enum) enum_map[str]); - has_cmd = true; - } - } - - boost::optional<odtone::mih::mih_cmd_list> supp_cmd; - if(has_cmd) - supp_cmd = commands; - - return supp_cmd; -} - -/////////////////////////////////////////////////////////////////////////////// -/** - * This class provides an implementation of an IEEE 802.21 MIH-User. - */ -class mih_user : boost::noncopyable { -public: - /** - * Construct the MIH-User. - * - * @param cfg Configuration options. - * @param io The io_service object that the MIH-User will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io); - - /** - * Destruct the MIH-User. - */ - ~mih_user(); - -protected: - /** - * User registration handler. - * - * @param cfg Configuration options. - * @param ec Error Code. - */ - void user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec); - - /** - * Default MIH event handler. - * - * @param msg Received message. - * @param ec Error code. - */ - void event_handler(odtone::mih::message& msg, const boost::system::error_code& ec); - - /** - * Capability Discover handler. - * - * @param msg Received message. - * @param ec Error Code. - */ - void receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - - /** - * Event subscribe handler. - * - * @param msg Received message. - * @param ec Error Code. - */ - void receive_MIH_Event_Subscribe_response(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_Link_Configure_Thresholds_request(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Configure_Thresholds_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_Link_Get_Parameters_request(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Get_Parameters_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Detected_indication(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_Link_Actions_request(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Actions_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Up_indication(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Down_indication(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_Event_Unsubscribe_request(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Parameters_Report(odtone::mih::message& msg, const boost::system::error_code& ec); - - void print_l2_3gpp_addr(odtone::mih::link_type& link_type, odtone::mih::l2_3gpp_addr& l2_3gpp_addr); - - -private: - odtone::sap::user _mihf; /**< User SAP helper. */ - odtone::mih::id _mihfid; /**< MIHF destination ID. */ - odtone::mih::id _mihuserid; /**< MIH_USER ID. */ - odtone::uint link_get_parameters_request, link_action_request, link_threshold_request; - odtone::uint link_last_action_sent, link_activate_counter; - odtone::mih::net_type_addr rcv_net_type_addr; - odtone::mih::link_id rcv_link_id; -}; - -/** - * Construct the MIH-User. - * - * @param cfg Configuration options. - * @param io The io_service object that the MIH-User will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ -//----------------------------------------------------------------------------- -mih_user::mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io) - : _mihf(cfg, io, boost::bind(&mih_user::event_handler, this, _1, _2)) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - boost::optional<odtone::mih::mih_cmd_list> supp_cmd = parse_supported_commands(cfg); - - link_get_parameters_request = 0; - link_action_request = 0; - link_threshold_request = 0; - link_last_action_sent = 0; - link_activate_counter = 0; - - m << odtone::mih::indication(odtone::mih::indication::user_register) - & odtone::mih::tlv_command_list(supp_cmd); - - log_(0, "User Register Indication - SENT "); - log_(0, " - User Name: ", m.source().to_string()); - log_(0, " "); - - odtone::mih::octet_string user_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_id); - _mihuserid.assign(user_id.c_str()); - - odtone::mih::octet_string dest_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_dest); - _mihfid.assign("mihf1"); - - log_(0, "[MSC_NEW][",getTimeStamp4Log(),"][MIH-USER=",_mihuserid.to_string(),"]\n"); - m.source(_mihuserid); - m.destination(_mihfid); - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_User_Register.indication --->]["+m.destination().to_string()+"]\n"); - _mihf.async_send(m, boost::bind(&mih_user::user_reg_handler, this, boost::cref(cfg), _2)); -} - - -/** - * Destruct the MIH-User. - */ -//----------------------------------------------------------------------------- -mih_user::~mih_user() -//----------------------------------------------------------------------------- -{ -} - -/** - * Print 3GPP Address. - * - * @param link_type Link Type. - * @param l2_3gpp_addr 3GPP Address. - */ -//----------------------------------------------------------------------------- -void mih_user::print_l2_3gpp_addr(odtone::mih::link_type& link_type, odtone::mih::l2_3gpp_addr& l2_3gpp_addr) -//----------------------------------------------------------------------------- -{ - odtone::uint iter; - if(link_type == odtone::mih::link_type_umts){ - log_(0, "\t Link Type: UMTS"); - } - if(link_type == odtone::mih::link_type_lte){ - log_(0, "\t Link Type: LTE"); - } - if((link_type == odtone::mih::link_type_umts)||(link_type == odtone::mih::link_type_lte)){ - //log_(0, "\t 3GPP Address: "); - std::printf("[mih_usr]: \t 3GPP Address: "); - for(iter=0; iter<l2_3gpp_addr.value.length(); iter++) - { - std::printf("-%hhx-", l2_3gpp_addr.value[iter]); - } - std::printf("\n"); - } -} - -/** - * User registration handler. - * - * @param cfg Configuration options. - * @param ec Error Code. - */ -//----------------------------------------------------------------------------- -void mih_user::user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH-User register result: ", ec.message()); - log_(0, ""); - - odtone::mih::message msg; - - odtone::mih::octet_string destination = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_dest); - _mihfid.assign(destination.c_str()); - - // - // Let's fire a capability discover request to get things moving - // - msg << odtone::mih::request(odtone::mih::request::capability_discover, _mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihuserid.to_string() +"][--- MIH_Capability_Discover.request --->]["+msg.destination().to_string()+"]\n"); - _mihf.async_send(msg, boost::bind(&mih_user::receive_MIH_Capability_Discover_confirm, this, _1, _2)); - - log_(0, "MIH_Capability_Discover.request - SENT (towards its local MIHF)"); - log_(0, ""); -} - -/** - * Default MIH event handler. - * - * @param msg Received message. - * @param ec Error code. - */ -//----------------------------------------------------------------------------- -void mih_user::event_handler(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - switch (msg.mid()) { - case odtone::mih::indication::link_up: - mih_user::receive_MIH_Link_Up_indication(msg, ec); - break; - - case odtone::mih::indication::link_down: - mih_user::receive_MIH_Link_Down_indication(msg, ec); - //sleep(2); - mih_user::send_MIH_Link_Get_Parameters_request(msg, ec); - break; - - case odtone::mih::indication::link_detected: - mih_user::receive_MIH_Link_Detected_indication(msg, ec); - // monitor signal strength - do not change (up/down) signal strength report now - //system ("sendip -d 0x00 -p ipv4 -is 127.0.0.1 -p udp -ud 22222 -us 65535 127.0.0.1"); - - //sleep(2); - link_action_request = 0; - mih_user::send_MIH_Link_Actions_request(msg, ec); - break; - - case odtone::mih::indication::link_going_down: - mih_user::receive_MIH_Link_Going_Down_indication(msg,ec); - //sleep(10); - link_get_parameters_request = 2; - mih_user::send_MIH_Link_Get_Parameters_request(msg, ec); - break; - - case odtone::mih::indication::link_handover_imminent: - log_(0, "MIH-User has received a local event \"link_handover_imminent\""); - break; - case odtone::mih::indication::link_handover_complete: - log_(0, "MIH-User has received a local event \"link_handover_complete\""); - break; - - case odtone::mih::confirm::link_configure_thresholds: - mih_user::receive_MIH_Link_Configure_Thresholds_confirm(msg, ec); - //sleep(2); - if (link_get_parameters_request == 0) { - link_get_parameters_request = 1; - mih_user::send_MIH_Link_Get_Parameters_request(msg, ec); - } - break; - - case odtone::mih::confirm::link_get_parameters: - switch(link_get_parameters_request){ - case 1: mih_user::receive_MIH_Link_Get_Parameters_confirm(msg, ec); - // monitor signal strength - increase signal strength report now - //system ("sendip -d 0x01 -p ipv4 -is 127.0.0.1 -p udp -ud 22222 -us 65535 127.0.0.1"); - break; - case 2: mih_user::receive_MIH_Link_Get_Parameters_confirm(msg, ec); - link_action_request = 1; - link_get_parameters_request = 3; - mih_user::send_MIH_Link_Actions_request(msg, ec); - break; - case 3: mih_user::receive_MIH_Link_Get_Parameters_confirm(msg, ec); - mih_user::send_MIH_Event_Unsubscribe_request(msg, ec); - break; - } - break; - - mih_user::receive_MIH_Link_Get_Parameters_confirm(msg, ec); - //sleep(1); - break; - - case odtone::mih::confirm::link_actions: - mih_user::receive_MIH_Link_Actions_confirm(msg, ec); - if (link_action_request == 0) { - link_action_request = 1; - mih_user::send_MIH_Link_Actions_request(msg, ec); - } else if (link_action_request == 1) { - // monitor signal strength - increase signal strength report now - //system ("sendip -d 0x01 -p ipv4 -is 127.0.0.1 -p udp -ud 22222 -us 65535 127.0.0.1"); - } - #ifdef TEST_DEACTIVATION - if ((link_activate_counter<NUM_ACT_DEACT)&&(link_activate_counter > 0)) { - sleep(20); - mih_user::send_MIH_Link_Actions_request(msg, ec); - } - if (link_activate_counter==NUM_ACT_DEACT) - log_(0, "TEST_DEACTIVATION completed \n"); - #endif - break; - - case odtone::mih::confirm::event_unsubscribe: - mih_user::receive_MIH_Event_Unsubscribe_confirm(msg, ec); - break; - - case odtone::mih::indication::link_parameters_report: - mih_user::receive_MIH_Link_Parameters_Report(msg, ec); - if (link_threshold_request == 1) { - // monitor signal strength - do not modify signal strength report now - //system ("sendip -d 0x0x00 -p ipv4 -is 127.0.0.1 -p udp -ud 22222 -us 65535 127.0.0.1"); - link_action_request = 2; - mih_user::send_MIH_Link_Actions_request(msg, ec); - - } else if (link_action_request == 1) { - // monitor signal strength - decrease signal strength report now - //system ("sendip -d 0xFF -p ipv4 -is 127.0.0.1 -p udp -ud 22222 -us 65535 127.0.0.1"); - // select decreasing down to low threshold - link_threshold_request = 1; - mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec); - } - break; - } -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Parameters_Report(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id link; - odtone::mih::link_param_rpt_list lprl; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_link_param_rpt_list(lprl); - - log_(0, ""); - log_(0, "MIH_Link_Parameters_Report.indication - RECEIVED - Begin"); - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Parameters_Report.indication --->]["+msg.destination().to_string()+"]\n"); - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link.addr); - print_l2_3gpp_addr(link.type, local_l2_3gpp_addr); - log_(0, "MIH_Link_Parameters_Report.indication - End"); -} - - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::status st; - odtone::mih::link_tuple_id link; - boost::optional<odtone::mih::mih_evt_list> evt; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_event_list(evt); - - log_(0, ""); - log_(0, "receive_MIH_Event_Unsubscribe_confirm - Begin"); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Unsubscribe.confirm\\n"+status2string(st.get()).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - log_(0, "\t- STATUS: ", status2string(st.get()).c_str(), " ", st.get()); - log_(0, "\t- MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - log_(0, "receive_MIH_Event_Unsubscribe_confirm - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Event_Unsubscribe_request(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - odtone::mih::link_tuple_id link; - odtone::mih::mih_evt_list events; - odtone::mih::l2_3gpp_addr l2_3gpp_addr; - - link.type = rcv_link_id.type; - //address UMTS - link.addr = rcv_link_id.addr; - - events.set(odtone::mih::mih_evt_link_detected); - events.set(odtone::mih::mih_evt_link_up); - events.set(odtone::mih::mih_evt_link_down); - events.set(odtone::mih::mih_evt_link_parameters_report); - events.set(odtone::mih::mih_evt_link_going_down); - - log_(0, ""); - log_(0, "send_MIH_Event_Unsubscribe_request - Begin"); - m << odtone::mih::request(odtone::mih::request::event_unsubscribe) - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_event_list(events); - - m.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Event_Unsubscribe.request --->]["+m.destination().to_string()+"]\n"); - _mihf.async_send(m, boost::bind(&mih_user::event_handler, this, _1, _2)); - - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(events).c_str()); - log_(0, "send_MIH_Event_Unsubscribe_request - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Down_indication(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id link; - odtone::mih::link_dn_reason ldr; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0, ""); - log_(0, "receive_MIH_Link_Down_indication - Begin"); - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_link_dn_reason(ldr); - - - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link.addr); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Down.indication\\n"+link_down_reason2string(ldr).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - - print_l2_3gpp_addr(link.type, local_l2_3gpp_addr); - - log_(0, " Link down reason: ", link_down_reason2string(ldr).c_str()); - log_(0, "receive_MIH_Link_Down_indication - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id link; - odtone::mih::link_gd_reason lgd; - odtone::mih::link_ac_ex_time ex_time; - - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0, ""); - log_(0, "receive_MIH_Link_Going_Down_indication - Begin"); - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_time_interval(ex_time) - & odtone::mih::tlv_link_gd_reason(lgd); - - - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link.addr); - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link.addr); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Going_Down.indication\\n"+link_going_down_reason2string(lgd).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - - print_l2_3gpp_addr(link.type, local_l2_3gpp_addr); - log_(0, "\tTime Interval :", (ex_time/256)); - - log_(0, "\tLink going down reason: ", link_going_down_reason2string(lgd).c_str()); - - log_(0, "receive_MIH_Link_Going_Down_indication - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Up_indication(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id link; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link); - - log_(0, ""); - log_(0, "receive_MIH_Link_Up_indication - Begin"); - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Up.indication --->]["+msg.destination().to_string()+"]\n"); - - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link.addr); - print_l2_3gpp_addr(link.type, local_l2_3gpp_addr); - log_(0, "receive_MIH_Link_Up_indication - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Actions_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - - log_(0, ""); - log_(0, "receive_MIH_Link_Actions_confirm - Begin"); - - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - odtone::mih::status st; - boost::optional<odtone::mih::link_action_rsp_list> larl; - /*odtone::mih::link_action_rsp_list larl; - odtone::mih::link_action_rsp lar; - - odtone::mih::link_scan_rsp_list lsrl; - odtone::mih::link_scan_rsp lsr; - - odtone::uint i, l, n, p; - odtone::mih::link_id link; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - odtone::mih::l2_3gpp_3g_cell_id local_l2_3gpp_3g_cell_id; - odtone::mih::link_scan_rsp_list local_link_scan_rsp_list; - odtone::sint8 local_sig_strength;*/ - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_action_rsp_list(larl); - - #ifdef TEST_DEACTIVATION - if (mih_user::link_last_action_sent==1){ - mih_user::link_activate_counter++; - } - #endif - - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Actions.confirm\\n"+status2string(st.get())+" --->]["+msg.destination().to_string()+"]\n"); - log_(0, "\t- STATUS: ", status2string(st.get()), " " , st.get()); - - /*log_(0, " - LINK ACTION RSP LIST - Length:", larl.size()); - - for(i=0; i< larl.size(); i++) - { - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(larl[i].id.addr); - print_l2_3gpp_addr(larl[i].id.type, local_l2_3gpp_addr); - - if(larl[i].result == odtone::mih::link_ac_success){log_(0, " Link Action Success");} - if(larl[i].result == odtone::mih::link_ac_failure){log_(0, " Link Action Failure");} - if(larl[i].result == odtone::mih::link_ac_refused){log_(0, " Link Action Refused");} - if(larl[i].result == odtone::mih::link_ac_incapable){log_(0, " Link Action Incapable");} - - local_link_scan_rsp_list = boost::get<odtone::mih::link_scan_rsp_list>(larl[i].scan_list); - - log_(0, " Link Scan Rsp List - Element: ", local_link_scan_rsp_list.size()); - for(l=0; l<local_link_scan_rsp_list.size(); l++) - { - //link_addr - local_l2_3gpp_3g_cell_id = boost::get<odtone::mih::l2_3gpp_3g_cell_id>(local_link_scan_rsp_list[l].id); - - log_(0, " 3GPP Cell ID Adress: ", local_link_scan_rsp_list.size()); - for(p=0; p<3; p++) { - std::printf("[mih_usr]: "); - std::printf(" Plmn %d: %d", p, local_l2_3gpp_3g_cell_id.plmn_id[p]); - } - log_(0, " Cell-ID: ", (local_l2_3gpp_3g_cell_id._cell_id/); - //net_id network identifier - log_(0, " Network Identifier: "); - std::printf("[mih_usr]: "); - for(n=0; n<local_link_scan_rsp_list[l].net_id.size(); n++) - { - std::printf("%c", local_link_scan_rsp_list[l].net_id[n]); - } - std::printf("\n"); - //sig_strength - local_sig_strength = boost::get<odtone::sint8>(local_link_scan_rsp_list[l].signal); - std::printf("[mih_usr]: "); - std::printf("Signal Strength: %d \n", local_sig_strength); - //log_(0, " Signal Strength: ", local_sig_strength); - } - log_(0, " "); - } -*/ - log_(0, "MIH_Link_Actions.confirm - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Actions_request(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - odtone::mih::link_action_list lal; - odtone::mih::link_action_req link_act_req; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0, ""); - log_(0, "send_MIH_Link_Actions_request - Begin"); - //address UMTS - link_act_req.id.type = rcv_link_id.type; - link_act_req.id.addr = rcv_link_id.addr; - - if(mih_user::link_action_request == 0){ - link_act_req.action.type = odtone::mih::link_ac_type_power_up; - link_act_req.action.attr.set(odtone::mih::link_ac_attr_scan); - log_(0, "Initial Scan, link_action_request = 0"); - //link_act_req.action.param...; - } else if((mih_user::link_activate_counter == 0)&&(mih_user::link_action_request == 1)) { - link_act_req.action.type = odtone::mih::link_ac_type_power_up; - mih_user::link_last_action_sent=1; - //mih_user::link_activate_counter++; - log_(0, "Initial Activation, link_action_request = 1"); - #ifndef TEST_DEACTIVATION - } else if(mih_user::link_action_request == 2) { - link_act_req.action.type = odtone::mih::link_ac_type_power_down; - log_(0, "Link Going Down Deactivation, link_action_request = 2"); - #endif - } - #ifdef TEST_DEACTIVATION - else if ((mih_user::link_activate_counter>0)&&(mih_user::link_action_request >= 1)){ - if (mih_user::link_last_action_sent==1){ - link_act_req.action.type = odtone::mih::link_ac_type_power_down; - mih_user::link_last_action_sent=0; - log_(0, "New Deactivation, link_action_request >1"); - } else { - link_act_req.action.type = odtone::mih::link_ac_type_power_up; - mih_user::link_last_action_sent=1; - //mih_user::link_activate_counter++; - log_(0, "New Activation, link_action_request >1"); - } - } - #endif - link_act_req.ex_time = 0; - - lal.push_back(link_act_req); - - - m << odtone::mih::request(odtone::mih::request::link_actions) - & odtone::mih::tlv_link_action_list(lal); - - - log_(0, "\t- LINK_ID: "); - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link_act_req.id.addr); - print_l2_3gpp_addr(link_act_req.id.type, local_l2_3gpp_addr); - - log_(0, "\t- Link Actions: " + link_actions_req2string(link_act_req)); - - m.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.destination().to_string() +"][--- MIH_Link_Actions.request\\n"+link_actions_req2string(link_act_req)+" --->]["+msg.source().to_string()+"]\n"); - _mihf.async_send(m, boost::bind(&mih_user::event_handler, this, _1, _2)); - - log_(0, "send_MIH_Link_Actions_request - End"); - log_(0, ""); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Detected_indication(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_det_info_list ldil; - - log_(0, ""); - log_(0, "receive_MIH_Link_Detected_indication - Begin"); - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_det_info_list(ldil); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Detected.indication --->]["+msg.destination().to_string()+"]\n"); - - log_(0, "receive_MIH_Link_Detected_indication - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Get_Parameters_request(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - odtone::mih::dev_states_req dsr; - odtone::uint iter; - - odtone::mih::link_id li; - odtone::mih::link_id_list lil; - - odtone::mih::link_status_req lsr; - - log_(0,""); - log_(0, "send_MIH_Link_Get_Parameters_request - Begin"); - - //set values - dsr.set(odtone::mih::dev_state_device_info); //optional - - li.type = rcv_link_id.type; - li.addr = rcv_link_id.addr; - lil.push_back(li); - odtone::mih::link_param_gen lp1; - //odtone::mih::link_param_gen lp2, lp3, lp4, lp5; - - lp1 = odtone::mih::link_param_gen_data_rate; - lsr._param_type_list.push_back(lp1); - - /*lp2 = odtone::mih::link_param_gen_sinr; - lsr._param_type_list.push_back(lp2); - - lp3 = odtone::mih::link_param_gen_packet_error_rate; - lsr._param_type_list.push_back(lp3); - - lp4 = odtone::mih::link_param_gen_throughput; - lsr._param_type_list.push_back(lp4); - - lp5 = odtone::mih::link_param_gen_signal_strength; - lsr._param_type_list.push_back(lp5);*/ - - lsr._states_req.set(odtone::mih::link_states_req_op_mode); - lsr._states_req.set(odtone::mih::link_states_req_channel_id); - lsr._desc_req.set(odtone::mih::link_desc_req_classes_of_service_supported); - - - m << odtone::mih::request(odtone::mih::request::link_get_parameters) - & odtone::mih::tlv_dev_states_req(dsr) - & odtone::mih::tlv_link_id_list(lil) - & odtone::mih::tlv_get_status_req_set(lsr); - - m.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.destination().to_string() +"][--- MIH_Link_Get_Parameters.request --->]["+msg.source().to_string()+"]\n"); - _mihf.async_send(m, boost::bind(&mih_user::event_handler, this, _1, _2)); - - //log_(0, " - DEVICE STATES REQUEST"); - - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0, "\t- LINK ID LIST - Length: ", lil.size()); - - for(iter=0; iter<lil.size(); iter++) - { - log_(0, "\t LINK ID ", iter); - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(lil[iter].addr); - print_l2_3gpp_addr(lil[iter].type, local_l2_3gpp_addr); - } - - log_(0, "\t- GET STATUS REQUEST "); - if(lsr._states_req.get(odtone::mih::link_states_req_op_mode) == 1) {log_(0, "\t Link power mode requested");} - if(lsr._states_req.get(odtone::mih::link_states_req_channel_id) == 1) {log_(0, "\t Channel identifier requested (as defined in the specific link technology)");} - - if(lp1 == odtone::mih::link_param_gen_data_rate) {log_(0, "\t DATA RATE link parameter requested");} - if(lp1 == odtone::mih::link_param_gen_signal_strength) {log_(0, "\t SIGNAL STRENGTH link parameter is required");} - if(lp1 == odtone::mih::link_param_gen_sinr) {log_(0, "\t SINR link parameter is required");} - if(lp1 == odtone::mih::link_param_gen_throughput) {log_(0, "\t THROUGHPUT link parameter is required");} - - log_(0, "\t- LINK DESCRIPTOR REQUESTED "); - - if(lsr._desc_req.get(odtone::mih::link_desc_req_classes_of_service_supported) == 1) {log_(0, "\t Number of CoS Supported ");} - if(lsr._desc_req.get(odtone::mih::link_desc_req_queues_supported) == 1) {log_(0, "\t Number of Queues Supported ");} - log_(0, "send_MIH_Link_Get_Parameters_request - End"); - log_(0, ""); - -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Get_Parameters_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - - odtone::mih::status st; - odtone::mih::status_rsp_list srl; - - odtone::uint iter; - - log_(0, ""); - log_(0, "receive_MIH_Link_Get_Parameters_confirm - Begin"); - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_get_status_rsp_list(srl); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihfid.to_string() +"][--- MIH_Link_Get_Parameters.confirm\\n"+status2string(st.get()).c_str()+" --->]["+_mihuserid.to_string()+"]\n"); - log_(0, "\t- STATUS: ", status2string(st.get()), " ", st.get()); - - - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0, "\t- STATUS RSP LIST - Length: ", srl.size()); - - for(iter=0; iter<srl.size(); iter++) - { - log_(0, "\t LINK ID ", iter+1, ":"); - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(srl[iter].id.addr); - print_l2_3gpp_addr(srl[iter].id.type, local_l2_3gpp_addr); - log_(0, "\t LINK STATUS RSP List - Element: ", iter+1); - - /*odtone::uint iter1; - - log_(0, " States Rsp List - Length: ", srl[iter].rsp.states_rsp_list.size()); - //States Rsp List (vector) - for(iter1=0; iter1<srl[iter1].rsp.states_rsp_list.size(); iter1++) - { - //each element op_mode or channel_id - log_(0, " Element:", iter1+1, " - Value:", srl[iter1].rsp.states_rsp_list[iter1]); - } - - log_(0, " Param List - Length: ", srl[iter].rsp.param_list.size()); - //Param List - for(iter1=0; iter1<srl[iter1].rsp.param_list.size(); iter1++) - { - //log_(0, "Element:", iter+1, "Type: ", srl[iter1].rsp.param_list[iter1].type ,"Value: ", srl[iter1].rsp.param_list[iter1]); - // 1 - link_param_type - // 2 - boost::variant<link_param_val, qos_param_val> - } - - log_(0, " Desc_rsp_list - Length: ", srl[iter].rsp.desc_rsp_list.size()); - //Desc_rsp_list - for(iter1=0; iter1<srl[iter1].rsp.desc_rsp_list.size(); iter1++) - { - //log_(0, "Element:", iter+1, "Value", srl[iter1].rsp.desc_rsp_list[iter1]); - //boost::variant<num_cos, num_queue> - //uint8 num_cos - uint8 num_queue - }*/ - } - log_(0, "receive_MIH_Link_Get_Parameters_confirm - End"); - -} - - -/** - * Capability Discover handler. - * - * @param msg Received message. - * @param ec Error Code. - */ -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - log_(0, ""); - log_(0, "receive_MIH_Capability_Discover_confirm - Begin"); - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - odtone::mih::status st; - boost::optional<odtone::mih::net_type_addr_list> ntal; - boost::optional<odtone::mih::mih_evt_list> evt; - - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - odtone::mih::link_tuple_id li; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_net_type_addr_list(ntal) - & odtone::mih::tlv_event_list(evt); - // MIH_TRANS_LIST could be added - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihfid.to_string() ,"][--- MIH_Capability_Discover.confirm\\nstatus=", status2string(st.get()).c_str(), - "\\nEvent list=",evt2string(evt.get()).c_str(), - "\\nNet type addr list=" , net_type_addr_list2string(ntal).c_str(), - " --->][",_mihuserid.to_string(),"]\n"); - log_(0, "\t- STATUS: ", status2string(st.get()), " " ,st.get()); - - if (evt) { - log_(0, "\t- MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - - //log_(0, "MIH-User has received a Capability_Discover.response with status ", - // st.get(), " and the following capabilities:"); - - log_(0, "\t- LIST(NET_TYPE_ADDR) - Network Types and Link Address:"); - - if (ntal) { - for (odtone::mih::net_type_addr_list::iterator i = ntal->begin(); i != ntal->end(); ++i) - { - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(i->addr); - li.type = boost::get<odtone::mih::link_type>(i->nettype.link); - - rcv_net_type_addr.addr = boost::get<odtone::mih::l2_3gpp_addr>(i->addr); - rcv_net_type_addr.nettype.link = boost::get<odtone::mih::link_type>(i->nettype.link); - - rcv_link_id.addr = boost::get<odtone::mih::l2_3gpp_addr>(i->addr); - rcv_link_id.type = boost::get<odtone::mih::link_type>(i->nettype.link); - - print_l2_3gpp_addr(li.type, local_l2_3gpp_addr); - // should be the same print - //print_l2_3gpp_addr(rcv_link_id.type, rcv_link_id.addr); - - //log_(0, *i); - } - - } else { - log_(0, "none"); - } - - log_(0, ""); - // - // event subscription - // - // For every interface the MIHF sent in the - // Capability_Discover.response send an Event_Subscribe.request - // for all availabe events - // - if (ntal && evt) { - for (odtone::mih::net_type_addr_list::iterator i = ntal->begin(); i != ntal->end(); ++i) { - odtone::mih::message req; - odtone::mih::link_tuple_id li; - - if (i->nettype.link.which() == 1) - { - li.addr = i->addr; - li.type = boost::get<odtone::mih::link_type>(i->nettype.link); - - req << odtone::mih::request(odtone::mih::request::event_subscribe, _mihfid) - & odtone::mih::tlv_link_identifier(li) - & odtone::mih::tlv_event_list(evt); - - req.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihuserid.to_string() +"][--- MIH_Event_Subscribe.request"+ - "\\nLink="+link_tupple_id2string(li).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - " --->]["+_mihfid.to_string()+"]\n"); - _mihf.async_send(req, boost::bind(&mih_user::receive_MIH_Event_Subscribe_response, this, _1, _2)); - - log_(0, "MIH-User has sent Event_Subscribe.request to ", req.destination().to_string()); - - if (evt) { - log_(0, "\t- MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - } - } - } - log_(0, "receive_MIH_Capability_Discover_confirm - End"); -} - -/** - * Event subscribe handler. - * - * @param msg Received message. - * @param ec Error Code. - */ -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Event_Subscribe_response(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - //log_(0, __FUNCTION__, "(", msg.tid(), ")"); - log_(0, ""); - log_(0, "receive_MIH_Event_Subscribe_response - Begin"); - - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - odtone::mih::status st; - boost::optional<odtone::mih::mih_evt_list> evt; - - msg >> odtone::mih::response() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_event_list(evt); - - if (evt) { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihfid.to_string() +"][--- MIH_Event_Subscribe.response\\nstatus="+ - status2string(st.get()).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - " --->]["+_mihuserid.to_string()+"]\n"); - } else { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihfid.to_string() +"][--- MIH_Event_Subscribe.response\\nstatus="+ - status2string(st.get()).c_str()+ - " --->]["+_mihuserid.to_string()+"]\n"); - } - log_(0, " - STATUS: ", status2string(st.get()), " " ,st.get()); - - mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec); - log_(0, "receive_MIH_Event_Subscribe_response - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Configure_Thresholds_request(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - odtone::mih::threshold th; - std::vector<odtone::mih::threshold> thl; - - odtone::mih::link_tuple_id lti; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0,""); - log_(0, "send_MIH_Link_Configure_Thresholds_request - Begin"); - - //link_tuple_id - lti.type = rcv_link_id.type; - lti.addr = rcv_link_id.addr; - - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(lti.addr); - - //List of the link threshold parameters - odtone::mih::link_cfg_param_list lcpl; - odtone::mih::link_cfg_param lcp; - odtone::mih::link_param_gen lp; - - //link_param_gen_data_rate = 0, /**< Data rate. */ - //link_param_gen_signal_strength = 1, /**< Signal strength. */ - //link_param_gen_sinr = 2, /**< SINR. */ - //link_param_gen_throughput = 3, /**< Throughput. */ - //link_param_gen_packet_error_rate = 4, /**< Packet error rate. */ - lp = odtone::mih::link_param_gen_signal_strength; - - lcp.type = lp; - //th_action_normal = 0, /**< Set normal threshold. */ - //th_action_one_shot = 1, /**< Set one-shot threshold. */ - //th_action_cancel = 2 /**< Cancel threshold. */ - lcp.action = odtone::mih::th_action_one_shot; - - //above_threshold = 0, /**< Above threshold. */ - //below_threshold = 1, /**< Below threshold. */ - if (link_threshold_request == 0) { - th.threshold_val = THRESHOLD_HIGH_VAL; - th.threshold_x_dir = odtone::mih::threshold::above_threshold; - } else if (link_threshold_request == 0) { - th.threshold_val = THRESHOLD_LOW_VAL; - th.threshold_x_dir = odtone::mih::threshold::below_threshold; - } else { - th.threshold_val = THRESHOLD_LOW_VAL; - th.threshold_x_dir = odtone::mih::threshold::below_threshold; - } - - thl.push_back(th); - lcp.threshold_list = thl; - lcpl.push_back(lcp); - - m << odtone::mih::request(odtone::mih::request::link_configure_thresholds) - & odtone::mih::tlv_link_identifier(lti) - & odtone::mih::tlv_link_cfg_param_list(lcpl); - - m.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihuserid.to_string() +"][--- MIH_Link_Configure_Thresholds.request\\nlink="+ - link_tupple_id2string(lti).c_str() + - " --->]["+_mihfid.to_string()+"]\n"); - _mihf.async_send(m, boost::bind(&mih_user::event_handler, this, _1, _2)); - - - log_(0, "\t- LINK TUPLE ID - Network Types and Link Address:"); - print_l2_3gpp_addr(lti.type, local_l2_3gpp_addr); - - log_(0, "\t- LINK CFG PARAM LIST - Length: ", lcpl.size()); - - if(lp == odtone::mih::link_param_gen_data_rate) {log_(0, "\t Generic link parameter DATA RATE ");} - if(lp == odtone::mih::link_param_gen_signal_strength) {log_(0, "\t Generic link parameter SIGNAL STRENGTH");} - if(lp == odtone::mih::link_param_gen_sinr) {log_(0, "\t Generic link parameter SINR");} - if(lp == odtone::mih::link_param_gen_throughput) {log_(0, "\t Generic link parameter THROUGHPUT");} - - if(lcp.action == odtone::mih::th_action_normal) {log_(0, "\t Normal Threshold");} - if(lcp.action == odtone::mih::th_action_one_shot) {log_(0, "\t One Shot Threshold");} - if(lcp.action == odtone::mih::th_action_cancel) {log_(0, "\t Threshold to be canceled");} - - log_(0, "\t Threshold value: ", th.threshold_val); - - if(th.threshold_x_dir == odtone::mih::threshold::below_threshold) {log_(0, "\t Threshold direction BELOW");} - if(th.threshold_x_dir == odtone::mih::threshold::above_threshold) {log_(0, "\t Threshold direction ABOVE");} - - log_(0, "send_MIH_Link_Configure_Thresholds_request - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Configure_Thresholds_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - log_(0, ""); - log_(0, "receive_MIH_Link_Configure_Thresholds_confirm - Begin"); - - odtone::uint iter; - odtone::mih::status st; - - //boost::optional<odtone::mih::link_cfg_status_list> lcsl; - odtone::mih::link_cfg_status_list lcsl; - odtone::mih::link_cfg_status lcp; - odtone::mih::link_param_gen lp; - - odtone::mih::link_tuple_id lti; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_identifier(lti) - & odtone::mih::tlv_link_cfg_status_list(lcsl); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihfid.to_string() +"][--- MIH_Link_Configure_Thresholds.confirm\\nstatus="+status2string(st.get()).c_str()+" --->]["+_mihuserid.to_string()+"]\n"); - log_(0, "\t- STATUS: ", status2string(st.get()), " " ,st.get()); - - log_(0, "\t- LINK CFG STATUS LIST - Length: ", lcsl.size()); - - for(iter=0; iter<lcsl.size(); iter++) - { - log_(0, "\t Link Param Type: ", lcsl[0].type); - log_(0, "\t Threshold Val: ", (lcsl[0].thold.threshold_val/256)); - if(lcsl[0].thold.threshold_x_dir == odtone::mih::threshold::below_threshold) {log_(0, "\t Threshold direction BELOW");} - if(lcsl[0].thold.threshold_x_dir == odtone::mih::threshold::above_threshold) {log_(0, "\t Threshold direction ABOVE");} - if(lcsl[0].status == odtone::mih::status_success){log_(0, "\t Config Status: Success ");} - else {log_(0, "\t Config Status: ", lcsl[0].status);} - } - - log_(0, "receive_MIH_Link_Configure_Thresholds_confirm - End"); - log_(0,""); -} - -//----------------------------------------------------------------------------- -int main(int argc, char** argv) -//----------------------------------------------------------------------------- -{ - odtone::setup_crash_handler(); - - try { - boost::asio::io_service ios; - - // declare MIH Usr available options - po::options_description desc(odtone::mih::octet_string("MIH Usr Configuration")); - desc.add_options() - ("help", "Display configuration options") - (odtone::sap::kConf_File, po::value<std::string>()->default_value("mih_usr.conf"), "Configuration file") - (odtone::sap::kConf_Receive_Buffer_Len, po::value<uint>()->default_value(4096), "Receive buffer length") - (odtone::sap::kConf_Port, po::value<ushort>()->default_value(1234), "Listening port") - (odtone::sap::kConf_MIH_SAP_id, po::value<std::string>()->default_value("user"), "MIH-User ID") - (kConf_MIH_Commands, po::value<std::string>()->default_value(""), "MIH-User supported commands") - (odtone::sap::kConf_MIHF_Ip, po::value<std::string>()->default_value("127.0.0.1"), "Local MIHF IP address") - (odtone::sap::kConf_MIHF_Local_Port, po::value<ushort>()->default_value(1025), "Local MIHF communication port") - (odtone::sap::kConf_MIH_SAP_dest, po::value<std::string>()->default_value("mihf1"), "MIHF destination"); - - odtone::mih::config cfg(desc); - cfg.parse(argc, argv, odtone::sap::kConf_File); - - if (cfg.help()) { - std::cerr << desc << std::endl; - return EXIT_SUCCESS; - } - - mih_user usr(cfg, ios); - - ios.run(); - - } catch(std::exception& e) { - log_(0, "exception: ", e.what()); - } -} - -// EOF //////////////////////////////////////////////////////////////////////// diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.conf b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.conf deleted file mode 100755 index ab40db1085..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.conf +++ /dev/null @@ -1,42 +0,0 @@ -#=============================================================================== -# Brief : MIH-User configuration file -# Authors : Carlos Guimaraes <cguimaraes@av.it.pt> -# Bruno Santos <bsantos@av.it.pt> -#------------------------------------------------------------------------------- -# ODTONE - Open Dot Twenty One -# -# Copyright (C) 2009-2012 Universidade Aveiro -# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -# -# This software is distributed under a license. The full license -# agreement can be found in the file LICENSE in this distribution. -# This software may not be copied, modified, sold or distributed -# other than expressed in the named license agreement. -# -# This software is distributed without any warranty. -#=============================================================================== - -## -## User id -## -[user] -id = user_ue - -## -## Commands supported by the MIH-User -## -commands = mih_link_get_parameters, mih_link_configure_thresholds, mih_link_actions, mih_net_ho_candidate_query, mih_net_ho_commit, mih_n2n_ho_query_resources, mih_n2n_ho_commit, mih_n2n_ho_complete, mih_mn_ho_candidate_query, mih_mn_ho_commit, mih_mn_ho_complete - -## -## Port used for communication with MIHF -## -[conf] -port = 1235 - -## -## MIHF configuration. For the default demonstration leave as is. -## -[mihf] -local_port = 1025 - - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.cpp b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.cpp deleted file mode 100755 index 08ee34b3e9..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.cpp +++ /dev/null @@ -1,1412 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include <odtone/base.hpp> -#include <odtone/debug.hpp> -#include <odtone/logger.hpp> -#include <odtone/mih/request.hpp> -#include <odtone/mih/response.hpp> -#include <odtone/mih/indication.hpp> -#include <odtone/mih/confirm.hpp> -#include <odtone/mih/tlv_types.hpp> -#include <odtone/sap/user.hpp> - -#include <boost/utility.hpp> -#include <boost/bind.hpp> -#include <boost/tokenizer.hpp> -#include <boost/foreach.hpp> -#include <boost/format.hpp> - -#include <iostream> -#include <map> -#include <time.h> - -/////////////////////////////////////////////////////////////////////////////// - -// Definition of the scenario to execute -#define NB_OF_RESOURCES 4 // Should not exceed mih_user::_max_link_action_requests -//#define SCENARIO_1 // Sequentially activate and deactivate each resource -//#define SCENARIO_2 // Activate all resources, then deactivate all resources -#define NUM_PARM_REPORT 10 - -/////////////////////////////////////////////////////////////////////////////// -// The scenario coded in this MIH-USER demo is the following -// +--------+ +-----+ +---------+ -// |MIH_USER| |MIH-F| |LINK_SAP | -// +---+----+ +--+--+ +----+----+ -// | | | -// ... (start of MIH-F here) ... ... -// | |---------- Link_Capability_Discover.request --------X| -// ... (start of LINK_SAP here) ... ... -// | |<--------- Link_Register.indication -----------------| -// | |---------- Link_Capability_Discover.request -------->| -// | |<--------- Link_Capability_Discover.confirm ---------| -// | | | -// ... (start of MIH USER here) ... ... -// |---------- MIH_User_Register.indication ------------>| (supported_commands) | -// | | | -// |---------- MIH_Capability_Discover.request --------->| | -// |<--------- MIH_Capability_Discover.confirm ----------| | -// | | | -// |---------- MIH_Event_Subscribe.request ------------->|---------- Link_Event_Subscribe.request ------------>| -// |<--------- MIH_Event_Subscribe.confirm --------------|<--------- Link_Event_Subscribe.confirm -------------| -// | | | -// |---------- MIH_Link_Actions.request ---------------->|---------- Link_Actions.request -------------------->| -// | (POWER UP + SCAN) | (POWER UP + SCAN) | -// ... ... ... -// | | | -// |<--------- Link_Detected.indication -----------------|<--------- Link_Detected.indication -----------------| -// | | | -// |<--------- Link_Up.indication -----------------------|<--------- Link_Up.indication -----------------------| -// | | RRC Connection Reestablishment notification) | -// | | | -// |---------- MIH_Link_Configure_Thresholds.request --->|---------- Link_Configure_Thresholds.request ------->| -// | | | -// |<--------- Link_Up.indication -----------------------|<--------- Link_Up.indication -----------------------| -// | | (RRC Connection reconfiguration notification) | -// |<--------- MIH_Link_Configure_Thresholds.confirm ----|<--------- Link_Configure_Thresholds.confirm --------| -// | | | -// |<--------- MIH_Link_Parameters_Report.indication ----|<--------- MIH_Link_Parameters_Report.indication ----| -// ... ... ... -// |<--------- MIH_Link_Actions.confirm -----------------|<--------- Link_Actions.confirm ---------------------| -// | (Success) | | -// |<--------- MIH_Link_Parameters_Report.indication ----|<--------- MIH_Link_Parameters_Report.indication ----| -// ... ... ... -// |<--------- MIH_Link_Parameters_Report.indication ----|<--------- MIH_Link_Parameters_Report.indication ----| -// ... ... ... -// |<--------- MIH_Link_Parameters_Report.indication ----|<--------- MIH_Link_Parameters_Report.indication ----| -// ... ... ... -// etc etc etc - -/////////////////////////////////////////////////////////////////////////////// - -static const char* const kConf_MIH_Commands = "user.commands"; - -/////////////////////////////////////////////////////////////////////////////// - -namespace po = boost::program_options; - -using odtone::uint; -using odtone::ushort; -using odtone::sint8; - -odtone::logger log_("[mih_usr]", std::cout); - -/////////////////////////////////////////////////////////////////////////////// - -//----------------------------------------------------------------------------- -void __trim(odtone::mih::octet_string &str, const char chr) -//----------------------------------------------------------------------------- -{ - str.erase(std::remove(str.begin(), str.end(), chr), str.end()); -} -//----------------------------------------------------------------------------- -template <class T> std::string StringOf(T object) { -//----------------------------------------------------------------------------- - std::ostringstream os; - os << object; - return(os.str()); -} -//----------------------------------------------------------------------------- -std::string getTimeStamp4Log() -//----------------------------------------------------------------------------- -{ - std::stringstream ss (std::stringstream::in | std::stringstream::out); - struct timespec time_spec; - unsigned int time_now_micros; - unsigned int time_now_s; - clock_gettime (CLOCK_REALTIME, &time_spec); - time_now_s = (unsigned int) time_spec.tv_sec % 3600; - time_now_micros = (unsigned int) time_spec.tv_nsec/1000; - ss << time_now_s << ':' << time_now_micros; - return ss.str(); -} -//----------------------------------------------------------------------------- -std::string status2string(odtone::mih::status statusP){ -//----------------------------------------------------------------------------- - switch (statusP.get()) { - case odtone::mih::status_success: return "SUCCESS";break; - case odtone::mih::status_failure: return "UNSPECIFIED_FAILURE";break; - case odtone::mih::status_rejected: return "REJECTED";break; - case odtone::mih::status_authorization_failure: return "AUTHORIZATION_FAILURE";break; - case odtone::mih::status_network_error: return "NETWORK_ERROR";break; - default: return "UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string link_down_reason2string(odtone::mih::link_dn_reason reasonP){ -//----------------------------------------------------------------------------- - switch (reasonP.get()) { - case odtone::mih::link_dn_reason_explicit_disconnect: return "DN_REASON_EXPLICIT_DISCONNECT";break; - case odtone::mih::link_dn_reason_packet_timeout: return "DN_REASON_PACKET_TIMEOUT";break; - case odtone::mih::link_dn_reason_no_resource: return "DN_REASON_NO_RESOURCE";break; - case odtone::mih::link_dn_reason_no_broadcast: return "DN_REASON_NO_BROADCAST";break; - case odtone::mih::link_dn_reason_authentication_failure: return "DN_REASON_AUTHENTICATION_FAILURE";break; - case odtone::mih::link_dn_reason_billing_failure: return "DN_REASON_BILLING_FAILURE";break; - default: return "DN_REASON_UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string link_going_down_reason2string(odtone::mih::link_gd_reason reasonP){ -//----------------------------------------------------------------------------- - switch (reasonP.get()) { - case odtone::mih::link_gd_reason_explicit_disconnect: return "GD_REASON_EXPLICIT_DISCONNECT";break; - case odtone::mih::link_gd_reason_link_parameter_degrading: return "GD_REASON_PARAMETER_DEGRADING";break; - case odtone::mih::link_gd_reason_low_power: return "GD_REASON_LOW_POWER";break; - case odtone::mih::link_gd_reason_no_resource: return "GD_REASON_NO_RESOURCE";break; - default: return "GD_REASON_UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string evt2string(odtone::mih::mih_evt_list evtP){ -//----------------------------------------------------------------------------- - std::string s=std::string(" "); - if(evtP.get(odtone::mih::mih_evt_link_detected)) s += "DETECTED "; - if(evtP.get(odtone::mih::mih_evt_link_up)) s += "UP "; - if(evtP.get(odtone::mih::mih_evt_link_down)) s += "DOWN "; - if(evtP.get(odtone::mih::mih_evt_link_parameters_report)) s += "PARAMETERS_REPORT "; - if(evtP.get(odtone::mih::mih_evt_link_going_down)) s += "GOING_DOWN "; - if(evtP.get(odtone::mih::mih_evt_link_handover_imminent)) s += "HANDOVER_IMMINENT "; - if(evtP.get(odtone::mih::mih_evt_link_handover_complete)) s += "HANDOVER_COMPLETE "; - if(evtP.get(odtone::mih::mih_evt_link_pdu_transmit_status)) s += "PDU_TRANSMIT_STATUS "; - return s; -} -//----------------------------------------------------------------------------- -std::string cmd2string(odtone::mih::mih_cmd_list cmdP){ -//----------------------------------------------------------------------------- - std::string s=std::string(" "); - if(cmdP.get(odtone::mih::mih_cmd_link_get_parameters)) s += "Link_Get_Parameters "; - if(cmdP.get(odtone::mih::mih_cmd_link_configure_thresholds)) s += "Link_Configure_Thresholds "; - if(cmdP.get(odtone::mih::mih_cmd_link_actions)) s += "Link_Actions "; - if(cmdP.get(odtone::mih::mih_cmd_net_ho_candidate_query)) s += "Net_HO_Candidate_Query "; - if(cmdP.get(odtone::mih::mih_cmd_net_ho_commit)) s += "Net_HO_Commit "; - if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_query_resources)) s += "N2N_HO_Query_Resources "; - if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_commit)) s += "N2N_HO_Commit "; - if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_complete)) s += "N2N_HO_Complete "; - if(cmdP.get(odtone::mih::mih_cmd_mn_ho_candidate_query)) s += "MN_HO_Candidate_Query "; - if(cmdP.get(odtone::mih::mih_cmd_mn_ho_commit)) s += "MN_HO_Commit "; - if(cmdP.get(odtone::mih::mih_cmd_mn_ho_complete)) s += "MN_HO_Complete "; - return s; -} -//----------------------------------------------------------------------------- -std::string link_type2string(const odtone::mih::link_type& lt) -//----------------------------------------------------------------------------- -{ - switch (lt.get()) { - case odtone::mih::link_type_gsm: return "GSM"; break; - case odtone::mih::link_type_gprs: return "GPRS"; break; - case odtone::mih::link_type_edge: return "EDGE"; break; - case odtone::mih::link_type_ethernet: return "Ethernet"; break; - case odtone::mih::link_type_wireless_other: return "Other"; break; - case odtone::mih::link_type_802_11: return "IEEE 802.11"; break; - case odtone::mih::link_type_cdma2000: return "CDMA-2000"; break; - case odtone::mih::link_type_umts: return "UMTS"; break; - case odtone::mih::link_type_cdma2000_hrpd: return "CDMA-2000-HRPD"; break; - case odtone::mih::link_type_lte: return "LTE"; break; - case odtone::mih::link_type_802_16: return "IEEE 802.16"; break; - case odtone::mih::link_type_802_20: return "IEEE 802.20"; break; - case odtone::mih::link_type_802_22: return "IEEE 802.22"; break; - default: break; - } - return "Unknown link type"; -} -//----------------------------------------------------------------------------- -std::string link_addr2string(const odtone::mih::link_addr *addr) -//----------------------------------------------------------------------------- -{ - if (const odtone::mih::mac_addr *la = boost::get<odtone::mih::mac_addr>(addr)) { - return la->address(); - } - else if (const odtone::mih::l2_3gpp_3g_cell_id *la = boost::get<odtone::mih::l2_3gpp_3g_cell_id>(addr)) { - char plmn[16]; - sprintf(plmn, "%hhx:%hhx:%hhx", la->plmn_id[0], la->plmn_id[1], la->plmn_id[2]); - return str(boost::format("%s %d") % plmn % la->_cell_id); - } - else if (const odtone::mih::l2_3gpp_2g_cell_id *la = boost::get<odtone::mih::l2_3gpp_2g_cell_id>(addr)) { - char plmn[16]; - sprintf(plmn, "%hhx:%hhx:%hhx", la->plmn_id[0], la->plmn_id[1], la->plmn_id[2]); - return str(boost::format("%s %d %d") % plmn % la->_lac % la->_ci); - } - else if (const odtone::mih::l2_3gpp_addr *la = boost::get<odtone::mih::l2_3gpp_addr>(addr)) { - return la->value; - } - else if (const odtone::mih::l2_3gpp2_addr *la = boost::get<odtone::mih::l2_3gpp2_addr>(addr)) { - return la->value; - } - else if (const odtone::mih::other_l2_addr *la = boost::get<odtone::mih::other_l2_addr>(addr)) { - return la->value; - } - return "null"; -} -//----------------------------------------------------------------------------- -std::string l2_3gpp_3g_cell_id2string(odtone::mih::l2_3gpp_3g_cell_id& addr) -//----------------------------------------------------------------------------- -{ - char buffer[256]; - int index = 0; - - index += std::sprintf(&buffer[index], "plmn: -%hhx--%hhx--%hhx-\n", addr.plmn_id[0], addr.plmn_id[1], addr.plmn_id[2]); - index += std::sprintf(&buffer[index], "cell_id: %hhx\n", addr._cell_id); - return buffer; -} -//----------------------------------------------------------------------------- -std::string link_id2string(odtone::mih::link_id linkP) -//----------------------------------------------------------------------------- -{ - std::string s; - s = link_type2string(linkP.type.get()) + " " + link_addr2string(&linkP.addr); - return s; -} -//----------------------------------------------------------------------------- -std::string ip_addr2string(odtone::mih::ip_addr ip_addrP) { -//----------------------------------------------------------------------------- - std::string s; - switch (ip_addrP.type()) { - case odtone::mih::ip_addr::ipv4: s = "ipv4 "; break; - case odtone::mih::ip_addr::ipv6: s = "ipv6 "; break; - default: s = "Unkown type "; - } - s += ip_addrP.address(); - return s; -} -//----------------------------------------------------------------------------- -std::string ip_tuple2string(odtone::mih::ip_tuple ip_tupleP) { -//----------------------------------------------------------------------------- - char buffer[128]; - std::snprintf(buffer, 128, "%s/%d", ip_addr2string(ip_tupleP.ip).c_str(), ip_tupleP.port_val); - return buffer; -} -//----------------------------------------------------------------------------- -std::string ip_proto2string(odtone::mih::proto ip_protoP) { -//----------------------------------------------------------------------------- - switch (ip_protoP.get()) { - case odtone::mih::proto_tcp: return "TCP"; - case odtone::mih::proto_udp: return "UDP"; - default: break; - } - return "Unknown IP protocol"; -} -// TEMP : next 2 functions are commented to restore flow_id as a uint32 -// full structure will be updated later -/*//----------------------------------------------------------------------------- -std::string flow_id2string(odtone::mih::flow_id flowP) { -//----------------------------------------------------------------------------- - std::string s; - odtone::mih::ip_tuple ip; - ip = flowP.src; - s = "SRC = " + ip_tuple2string(flowP.src); - s += ", DST = " + ip_tuple2string(flowP.dst); - s += ", PROTO = " + ip_proto2string(flowP.transport); - return s; -} -//----------------------------------------------------------------------------- -std::string flow_id2string(odtone::mih::link_ac_param link_ac_paramP) { -//----------------------------------------------------------------------------- - if (odtone::mih::resource_desc *res = boost::get<odtone::mih::resource_desc>(&link_ac_paramP.param)) { - return flow_id2string(res->fid); - } - else if (odtone::mih::flow_attribute *flow = boost::get<odtone::mih::flow_attribute>(&link_ac_paramP.param)) { - return flow_id2string(flow->id); - } - return "null"; -}*/ -//----------------------------------------------------------------------------- -std::string link_ac_result2string(odtone::mih::link_ac_result resultP) -//----------------------------------------------------------------------------- -{ - switch (resultP.get()) { - case odtone::mih::link_ac_success: return "SUCCESS"; break; - case odtone::mih::link_ac_failure: return "FAILURE"; break; - case odtone::mih::link_ac_refused: return "REFUSED"; break; - case odtone::mih::link_ac_incapable: return "INCAPABLE"; break; - default: break; - } - return "Unknown action result"; -} -//----------------------------------------------------------------------------- -std::string link_actions_req2string(odtone::mih::link_action_req link_act_reqP) { -//----------------------------------------------------------------------------- - std::string s; - - s = link_id2string(link_act_reqP.id); - - if(link_act_reqP.action.type == odtone::mih::link_ac_type_none) s += ", AC_TYPE_NONE"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_disconnect) s += ", AC_TYPE_DISCONNECT"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_low_power) s += ", AC_TYPE_LOW_POWER"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_down) s += ", AC_TYPE_POWER_DOWN"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_up) s += ", AC_TYPE_POWER_UP"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_flow_attr) s += ", AC_TYPE_FLOW_ATTR"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_activate_resources) s += ", AC_TYPE_ACTIVATE_RESOURCES"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_deactivate_resources) s += ", AC_TYPE_DEACTIVATE_RESOURCES"; - - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_data_fwd_req)) s += ", AC_ATTR_DATA_FWD_REQ"; - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_scan)) s += ", AC_ATTR_SCAN"; - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_res_retain)) s += ", AC_ATTR_RES_RETAIN"; - - s += ", " + StringOf(link_act_reqP.ex_time) + " ms"; - return s; -} -//----------------------------------------------------------------------------- -std::string net_type_addr_list2string(boost::optional<odtone::mih::net_type_addr_list> ntalP) { -//----------------------------------------------------------------------------- - std::string s; - std::ostringstream stream; - odtone::mih::net_type_addr net_type_addr; - - for (odtone::mih::net_type_addr_list::iterator i = ntalP->begin(); i != ntalP->end(); i++) - { - net_type_addr = boost::get<odtone::mih::net_type_addr>(*i); - stream << net_type_addr; - if (i != ntalP->begin()) { - stream << " / "; - } - } - s = stream.str(); - return s; -} - - - -/** - * Parse supported commands. - * - * @param cfg Configuration options. - * @return An optional list of supported commands. - */ -boost::optional<odtone::mih::mih_cmd_list> parse_supported_commands(const odtone::mih::config &cfg) -{ - using namespace boost; - - odtone::mih::mih_cmd_list commands; - - std::map<std::string, odtone::mih::mih_cmd_list_enum> enum_map; - enum_map["mih_link_get_parameters"] = odtone::mih::mih_cmd_link_get_parameters; - enum_map["mih_link_configure_thresholds"] = odtone::mih::mih_cmd_link_configure_thresholds; - enum_map["mih_link_actions"] = odtone::mih::mih_cmd_link_actions; - enum_map["mih_net_ho_candidate_query"] = odtone::mih::mih_cmd_net_ho_candidate_query; - enum_map["mih_net_ho_commit"] = odtone::mih::mih_cmd_net_ho_commit; - enum_map["mih_n2n_ho_query_resources"] = odtone::mih::mih_cmd_n2n_ho_query_resources; - enum_map["mih_n2n_ho_commit"] = odtone::mih::mih_cmd_n2n_ho_commit; - enum_map["mih_n2n_ho_complete"] = odtone::mih::mih_cmd_n2n_ho_complete; - enum_map["mih_mn_ho_candidate_query"] = odtone::mih::mih_cmd_mn_ho_candidate_query; - enum_map["mih_mn_ho_commit"] = odtone::mih::mih_cmd_mn_ho_commit; - enum_map["mih_mn_ho_complete"] = odtone::mih::mih_cmd_mn_ho_complete; - - std::string tmp = cfg.get<std::string>(kConf_MIH_Commands); - __trim(tmp, ' '); - - char_separator<char> sep1(","); - tokenizer< char_separator<char> > list_tokens(tmp, sep1); - - BOOST_FOREACH(std::string str, list_tokens) { - if(enum_map.find(str) != enum_map.end()) { - commands.set((odtone::mih::mih_cmd_list_enum) enum_map[str]); - } - } - - return commands; -} - -/////////////////////////////////////////////////////////////////////////////// -/** - * This class provides an implementation of an IEEE 802.21 MIH-User. - */ -class mih_user : boost::noncopyable { -public: - /** - * Construct the MIH-User. - * - * @param cfg Configuration options. - * @param io The io_service object that the MIH-User will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io); - - /** - * Destruct the MIH-User. - */ - ~mih_user(); - -protected: - /** - * User registration handler. - * - * @param cfg Configuration options. - * @param ec Error Code. - */ - void user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec); - /** - * Default MIH event handler. - * - * @param msg Received event notification. - * @param ec Error code. - */ - void event_handler(odtone::mih::message& msg, const boost::system::error_code& ec); - /** - * MIH receive message handler. - * - * @param msg Received message. - * @param ec Error code. - */ - void receive_handler(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_User_Register_indication(const odtone::mih::config& cfg); - - void send_MIH_Capability_Discover_request(void); - void receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg); - - void send_MIH_Event_Subscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt); - void receive_MIH_Event_Subscribe_confirm(odtone::mih::message& msg); - - void send_MIH_Event_Unsubscribe_request(void); - void send_MIH_Event_Unsubscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt); - void receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg); - - void send_MIH_Link_Actions_request(const odtone::mih::link_id& link, odtone::mih::link_ac_type type); - void receive_MIH_Link_Actions_confirm(odtone::mih::message& msg); - void receive_MIH_Link_Parameters_Report(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_Link_Configure_Thresholds_request(odtone::mih::message& msg, const boost::system::error_code& ec); - void receive_MIH_Link_Configure_Thresholds_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - -private: - odtone::sap::user _mihf; /**< User SAP helper. */ - odtone::mih::id _mihfid; /**< MIHF destination ID. */ - odtone::mih::id _mihuserid; /**< MIH_USER ID. */ - - odtone::mih::ip_addr _mihf_ip; /**< MIHF IP address */ - odtone::mih::port _mihf_lport; /**< MIHF local port number */ - - odtone::mih::link_id_list _link_id_list; /**< List of network link identifiers */ - odtone::mih::mih_evt_list _subs_evt_list; /**< List of subscribed link events */ - - odtone::mih::link_ac_type _last_link_action_type; - odtone::uint _current_link_action_request, _nb_of_link_action_requests; - odtone::uint link_threshold_request, link_measures_request, link_measures_counter; - odtone::mih::link_id rcv_link_id; - - static const odtone::uint _max_link_action_requests = 4; - odtone::uint _num_thresholds_request; - - void receive_MIH_Link_Detected_indication(odtone::mih::message& msg); - void send_MIH_Link_Action_Power_Up_plus_scan_request(const odtone::mih::link_id& link); - void receive_MIH_Link_Up_indication(odtone::mih::message& msg); - - void receive_MIH_Link_Down_indication(odtone::mih::message& msg); - - void receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg); - -}; - -//----------------------------------------------------------------------------- -mih_user::mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io) - : _mihf(cfg, io, boost::bind(&mih_user::event_handler, this, _1, _2)), - _last_link_action_type(odtone::mih::link_ac_type_none), - _current_link_action_request(0), _nb_of_link_action_requests(NB_OF_RESOURCES), _num_thresholds_request(0) -//----------------------------------------------------------------------------- -{ - odtone::mih::octet_string user_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_id); - _mihuserid.assign(user_id.c_str()); - - odtone::mih::octet_string dest_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_dest); - _mihfid.assign(dest_id.c_str()); - - odtone::mih::octet_string src = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIHF_Ip); - boost::asio::ip::address ip = boost::asio::ip::address::from_string(src); - if (ip.is_v4()) { - odtone::mih::ip_addr ip_addr(odtone::mih::ip_addr::ipv4, src); - _mihf_ip = ip_addr; - } else if (ip.is_v6()) { - odtone::mih::ip_addr ip_addr(odtone::mih::ip_addr::ipv6, src); - _mihf_ip = ip_addr; - } - - _mihf_lport = cfg.get<odtone::mih::port>(odtone::sap::kConf_MIHF_Local_Port); - - //_nb_of_link_action_requests = NB_OF_RESOURCES; - if (_nb_of_link_action_requests > _max_link_action_requests) { - _nb_of_link_action_requests = _max_link_action_requests; - } - - _link_id_list.clear(); - _subs_evt_list.clear(); - link_threshold_request = 0; - link_measures_request =0; - link_measures_counter =0; - log_(0, "[MSC_NEW]["+getTimeStamp4Log()+"][MIH-USER="+_mihuserid.to_string()+"]\n"); - - // Send MEDIEVAL specific MIH_User_Register.indication message to the MIH-F - mih_user::send_MIH_User_Register_indication(cfg); -} - -//----------------------------------------------------------------------------- -mih_user::~mih_user() -//----------------------------------------------------------------------------- -{ -} - -//----------------------------------------------------------------------------- -void mih_user::user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH-User register result: ", ec.message(), "\n"); - - // - // Let's fire a capability discover request to get things moving - // - mih_user::send_MIH_Capability_Discover_request(); -} - -//----------------------------------------------------------------------------- -void mih_user::event_handler(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - switch (msg.mid()) { - case odtone::mih::indication::link_detected: - mih_user::receive_MIH_Link_Detected_indication(msg); - break; - - case odtone::mih::indication::link_up: - mih_user::receive_MIH_Link_Up_indication(msg); - if (_num_thresholds_request == 0) { - mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec); - _num_thresholds_request += 1;; - } - break; - - case odtone::mih::indication::link_down: - mih_user::receive_MIH_Link_Down_indication(msg); - break; - - case odtone::mih::indication::link_going_down: - mih_user::receive_MIH_Link_Going_Down_indication(msg); - break; - - case odtone::mih::indication::link_handover_imminent: - log_(0, "MIH-User has received a local event \"link_handover_imminent\""); - break; - - case odtone::mih::indication::link_handover_complete: - log_(0, "MIH-User has received a local event \"link_handover_complete\""); - break; - - case odtone::mih::indication::link_parameters_report: - //log_(0, "MIH-User has received a local event \"link_parameters_report\""); - mih_user::receive_MIH_Link_Parameters_Report(msg, ec); - /*if (link_threshold_request == 0){ - mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec); - link_threshold_request =1; - } else if (link_threshold_request == 1){ - link_measures_counter ++; - // Stop measures after 5 reports - if (link_measures_counter == NUM_PARM_REPORT){ - mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec); - } - }*/ - break; - - case odtone::mih::indication::link_pdu_transmit_status: - log_(0, "MIH-User has received a local event \"link_pdu_transmit_status\""); - break; - - case odtone::mih::confirm::link_configure_thresholds: - mih_user::receive_MIH_Link_Configure_Thresholds_confirm(msg, ec); - break; - - default: - log_(0, "MIH-User has received UNKNOWN local event"); - break; - } -} - -//----------------------------------------------------------------------------- -void mih_user::receive_handler(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - switch (msg.mid()) { - - case odtone::mih::confirm::capability_discover: - mih_user::receive_MIH_Capability_Discover_confirm(msg); - break; - - case odtone::mih::confirm::event_subscribe: - mih_user::receive_MIH_Event_Subscribe_confirm(msg); - break; - - case odtone::mih::confirm::event_unsubscribe: - mih_user::receive_MIH_Event_Unsubscribe_confirm(msg); - break; - - case odtone::mih::confirm::link_actions: - mih_user::receive_MIH_Link_Actions_confirm(msg); - break; - - default: - log_(0, "MIH-User has received UNKNOWN message (", msg.mid(), ")\n"); - break; - } -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Detected_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Detected.indication - RECEIVED - Begin\n"); - odtone::mih::link_det_info ldi; - odtone::mih::link_det_info_list ldil; - odtone::mih::link_det_info_list::iterator it_ldil; - odtone::mih::link_id lid; - - msg >> odtone::mih::indication() & odtone::mih::tlv_link_det_info_list(ldil); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Detected.indication --->]["+msg.destination().to_string()+"]\n"); - for(it_ldil = ldil.begin(); it_ldil != ldil.end(); it_ldil++) { - ldi = *it_ldil; - log_(0, "\tMIH_Link_Detected.indication - network_id:........", ldi.network_id.c_str()); - log_(0, "\tMIH_Link_Detected.indication - net_aux_id:........", ldi.net_aux_id.c_str()); - log_(0, "\tMIH_Link_Detected.indication - sig_strength:......TO DO");//, ldi.signal); - log_(0, "\tMIH_Link_Detected.indication - sinr:..............", ldi.sinr); - log_(0, "\tMIH_Link_Detected.indication - data_rate:.........", ldi.data_rate); - log_(0, "\tMIH_Link_Detected.indication - data_rate:.........", ldi.data_rate); - log_(0, "\tMIH_Link_Detected.indication - mih_capabilities:..", ldi.data_rate); - log_(0, "\tMIH_Link_Detected.indication - net_capabilities:..TO DO");//, ldi.net_capabilities); - - } - // Display message parameters - // TODO: for each link_det_info in the list {display LINK_DET_INFO} - - // send Link_Action / Power Up - lid.type = odtone::mih::link_type_lte; - lid.addr = ldi.id.addr; - //send_MIH_Link_Action_Power_Up_plus_scan_request(lid); - log_(0, "MIH_Link_Detected.indication - End\n"); -} - - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Action_Power_Up_plus_scan_request(const odtone::mih::link_id& link) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - odtone::mih::link_action_list lal; - odtone::mih::link_action_req link_act_req; - //struct null n; - - link_act_req.id = link; - link_act_req.action.type = odtone::mih::link_ac_type_power_up; - link_act_req.action.attr.clear(); - link_act_req.action.attr.set(odtone::mih::link_ac_attr_scan); - - link_act_req.ex_time = 5000; // in ms - - lal.push_back(link_act_req); - - m << odtone::mih::request(odtone::mih::request::link_actions) - & odtone::mih::tlv_link_action_list(lal); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Link_Actions.request\\n"+link_actions_req2string(link_act_req)+" --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH-User has sent Link_Actions.request to ", m.destination().to_string()); - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str()); - log_(0, " - LINK_ACTIONS - Link Actions: " + link_actions_req2string(link_act_req) + "\n"); - - log_(0, "MIH_Link_Action_Power_Up_request - SENT\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Up_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Up.indication - RECEIVED - Begin\n"); - - odtone::mih::link_tuple_id link; -// odtone::mih::tlv_old_access_router oldAR; - - msg >> odtone::mih::indication() & odtone::mih::tlv_link_identifier(link); -// & odtone::mih::tlv_old_access_router(oar); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Up.indication --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str(), "\n"); - - log_(0, "MIH_Link_Up.indication - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Down_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id link; - boost::optional<odtone::mih::link_addr> addr; - odtone::mih::link_dn_reason ldr; - - log_(0, "MIH_Link_Down.indication - RECEIVED - Begin\n"); - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_old_access_router(addr) - & odtone::mih::tlv_link_dn_reason(ldr); - -// log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Down.indication\\n"+link_down_reason2string(ldr).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - - //Display message parameters - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str(), "\n"); -// log_(0, " - LINK_DN_REASON - Link down reason: ", link_down_reason2string(ldr).c_str(), "\n"); - - log_(0, "MIH_Link_Down.indication - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Going_Down.indication - RECEIVED - Begin\n"); - - odtone::mih::link_tuple_id link; - odtone::mih::link_gd_reason lgd; - odtone::mih::link_ac_ex_time ex_time; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_time_interval(ex_time) - & odtone::mih::tlv_link_gd_reason(lgd); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Going_Down.indication\\n"+link_going_down_reason2string(lgd).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str()); - log_(0, " - Time Interval:", (ex_time/256)); - log_(0, " - LINK_GD_REASON - Link going down reason: ", link_going_down_reason2string(lgd).c_str(), "\n"); - - log_(0, "MIH_Link_Going_Down.indication - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Parameters_Report(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id link; - odtone::mih::link_param_rpt_list lprl; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_link_param_rpt_list(lprl); - - log_(0, ""); - log_(0, "MIH_Link_Parameters_Report.indication - RECEIVED - Begin"); - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Parameters_Report.indication --->]["+msg.destination().to_string()+"]\n"); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(link).c_str()); - log_(0, "MIH_Link_Parameters_Report.indication - End"); -} - - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_User_Register_indication(const odtone::mih::config& cfg) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - boost::optional<odtone::mih::mih_cmd_list> supp_cmd = parse_supported_commands(cfg); - - m << odtone::mih::indication(odtone::mih::indication::user_register) - & odtone::mih::tlv_command_list(supp_cmd); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_User_Register.indication --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::user_reg_handler, this, boost::cref(cfg), _2)); - - log_(0, "MIH_User_Register.indication - SENT (towards its local MIHF)\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Capability_Discover_request(void) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - m << odtone::mih::request(odtone::mih::request::capability_discover); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Capability_Discover.request --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH_Capability_Discover.request - SENT (towards its local MIHF)\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Capability_Discover.confirm - RECEIVED - Begin\n"); - - odtone::mih::status st; - boost::optional<odtone::mih::net_type_addr_list> ntal; - boost::optional<odtone::mih::mih_evt_list> evt; - boost::optional<odtone::mih::mih_cmd_list> cmd; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_net_type_addr_list(ntal) - & odtone::mih::tlv_event_list(evt) - & odtone::mih::tlv_command_list(cmd); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Capability_Discover.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - "\\nNet type addr list=" + net_type_addr_list2string(ntal).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - if (evt) { - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - if (cmd) { - log_(0, " - MIH_CMD_LIST - Command List: ", cmd2string(cmd.get()).c_str()); - } - if (ntal) { - log_(0, " - LIST(NET_TYPE_ADDR) - Network Types and Link Address: ", net_type_addr_list2string(ntal).c_str()); - //Store link address - for (odtone::mih::net_type_addr_list::iterator i = ntal->begin(); i != ntal->end(); i++) - { - rcv_link_id.addr = i->addr; - rcv_link_id.type = boost::get<odtone::mih::link_type>(i->nettype.link); - } - } - log_(0, ""); - - // - // event subscription - // - // For every interface the MIHF sent in the - // Capability_Discover.response send an Event_Subscribe.request - // for all availabe events - // - if (ntal && evt) { - _subs_evt_list = evt.get(); // save the list of subscribed link events - for (odtone::mih::net_type_addr_list::iterator i = ntal->begin(); i != ntal->end(); i++) { - if (i->nettype.link.which() == 1) - { - odtone::mih::link_tuple_id li; - - li.addr = i->addr; - li.type = boost::get<odtone::mih::link_type>(i->nettype.link); - _link_id_list.push_back(li); // save the link identifier of the network interface - - mih_user::send_MIH_Event_Subscribe_request(li, evt.get()); - } - } - } - - log_(0, "MIH_Capability_Discover.confirm - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Event_Subscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - m << odtone::mih::request(odtone::mih::request::event_subscribe) - & odtone::mih::tlv_link_identifier(li) - & odtone::mih::tlv_event_list(evt); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Event_Subscribe.request"+ - "\\nLink="+link_id2string(li).c_str()+ - "\\nEvent list="+evt2string(evt).c_str()+ - " --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH-User has sent Event_Subscribe.request to ", m.destination().to_string()); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(li).c_str()); - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt).c_str(), "\n"); - - log_(0, "MIH_Event_Subscribe.request - SENT\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Event_Subscribe_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Event_Subscribe.confirm(", msg.tid(), ") - RECEIVED - Begin\n"); - - odtone::mih::status st; - odtone::mih::link_tuple_id link; - boost::optional<odtone::mih::mih_evt_list> evt; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_event_list(evt); - - if (evt) { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Subscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } else { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Subscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(link).c_str()); - if (evt) { - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - log_(0, ""); - - //mih_user::send_MIH_Link_Actions_request(link, odtone::mih::link_ac_type_link_activate_resources); - //log_(0, "TEMP : Resource scenario deactivated\n"); - - log_(0, "MIH_Event_Subscribe.confirm - End\n"); - mih_user::send_MIH_Link_Action_Power_Up_plus_scan_request(link); - -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Event_Unsubscribe_request(void) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id li; - - // For every interface the MIH user received in the - // Capability_Discover.confirm, send an Event_Unsubscribe.request - // for all subscribed events - for (odtone::mih::link_id_list::iterator i = _link_id_list.begin(); i != _link_id_list.end(); i++) { - li.type = i->type; - li.addr = i->addr; - mih_user::send_MIH_Event_Unsubscribe_request(li, _subs_evt_list); - } -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Event_Unsubscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - m << odtone::mih::request(odtone::mih::request::event_unsubscribe) - & odtone::mih::tlv_link_identifier(li) - & odtone::mih::tlv_event_list(evt); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Event_Unsubscribe.request"+ - "\\nLink="+link_id2string(li).c_str()+ - "\\nEvent list="+evt2string(evt).c_str()+ - " --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH-User has sent Event_Unsubscribe.request to ", m.destination().to_string()); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(li).c_str()); - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt).c_str(), "\n"); - - log_(0, "MIH_Event_Unsubscribe.request - SENT\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Event_Unsubscribe.confirm(", msg.tid(), ") - RECEIVED - Begin\n"); - - odtone::mih::status st; - odtone::mih::link_tuple_id link; - boost::optional<odtone::mih::mih_evt_list> evt; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_event_list(evt); - - if (evt) { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Unsubscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } else { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Unsubscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(link).c_str()); - if (evt) { - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - log_(0, ""); - - log_(0, "MIH_Event_Unsubscribe.confirm - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Actions_request(const odtone::mih::link_id& link, odtone::mih::link_ac_type type) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - odtone::mih::link_action_list lal; - odtone::mih::link_action_req link_act_req; - - link_act_req.id = link; - link_act_req.action.type = type; - - _last_link_action_type = type; - - // Initialize resource parameters - odtone::mih::resource_desc res; - - res.lid = link; // Link identifier - res.data_rate = 128000; // bit rate - res.jumbo = false; // jumbo disable - res.multicast = false; // multicast disable - - odtone::mih::qos qos; // Class Of Service - qos.value = 56; - res.qos_val = qos; - res.fid = 555 + _current_link_action_request; - -// // Flow identifier -// res.fid.src.ip = _mihf_ip; -// res.fid.src.port_val = _mihf_lport; -// -// if (mih_user::_current_link_action_request == 0) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "2001:0660:0382:0014:0335:0600:8014:9150"); // DUMMY -// } -// else if (mih_user::_current_link_action_request == 1) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "2001:0660:0382:0014:0335:0600:8014:9151"); // DUMMY -// } -// else if (mih_user::_current_link_action_request == 2) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "FF3E:0020:2001:0DB8:0000:0000:0000:0043"); // DUMMY -// res.multicast = true; -// } -// else if (mih_user::_current_link_action_request == 3) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "2001:0660:0382:0014:0335:0600:8014:9153"); // DUMMY -// } -// res.fid.dst.port_val = 1235; // DUMMY -// res.fid.transport = odtone::mih::proto_udp; - - link_act_req.action.param.param = res; - - link_act_req.ex_time = 0; - - lal.push_back(link_act_req); - - m << odtone::mih::request(odtone::mih::request::link_actions) - & odtone::mih::tlv_link_action_list(lal); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Link_Actions.request\\n"+link_actions_req2string(link_act_req)+" --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH-User has sent Link_Actions.request to ", m.destination().to_string()); - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str()); - log_(0, " - FLOW_ID - Flow identifier: ", res.fid); -//TEMP log_(0, " - FLOW_ID - Flow identifier: ", flow_id2string(link_act_req.action.param).c_str()); - log_(0, " - LINK_ACTIONS - Link Actions: " + link_actions_req2string(link_act_req) + "\n"); - - log_(0, "MIH_Link_Actions.request - SENT\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Actions_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Actions.confirm - RECEIVED - Begin\n"); - - odtone::mih::status st; - boost::optional<odtone::mih::link_action_rsp_list> larl; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_action_rsp_list(larl); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Actions.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - if (larl) { - log_(0, " - LINK ACTION RSP LIST - Length:", larl.get().size()); - for (odtone::mih::link_action_rsp_list::iterator i = larl->begin(); i != larl->end(); i++) - { - log_(0, "\tLINK_ID: ", link_id2string(i->id).c_str(), - ", LINK_AC_RESULT: ", link_ac_result2string(i->result).c_str()); - } - } - log_(0, ""); - - // 1st scenario: Sequentially activate and deactivate each resource -#ifdef SCENARIO_1 - if (larl) { - odtone::mih::link_action_rsp *rsp = &larl->front(); - if (_current_link_action_request < _nb_of_link_action_requests) { - if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) { - if (rsp->result.get() == odtone::mih::link_ac_success) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources); - _current_link_action_request += 1; - } - } - else if (_last_link_action_type == odtone::mih::link_ac_type_link_deactivate_resources) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_activate_resources); - } - } - else { // Ends the scenario - mih_user::send_MIH_Event_Unsubscribe_request(); - } - } -#endif // SCENARIO_1 - -#ifdef SCENARIO_2 - // 2nd scenario: Activate all resources, then deactivate all resources - if (larl.get().size() > 0) { - odtone::mih::link_action_rsp *rsp = &larl->front(); - if (++_current_link_action_request < _nb_of_link_action_requests) { - if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_activate_resources); - } - else if (_last_link_action_type == odtone::mih::link_ac_type_link_deactivate_resources) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources); - } - } - else if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) { - _current_link_action_request = 0; - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources); - } - else { // Ends the scenario - mih_user::send_MIH_Event_Unsubscribe_request(); - } - } -#endif // SCENARIO_2 - - log_(0, "MIH_Link_Actions.confirm - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Configure_Thresholds_request(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - odtone::mih::threshold th; - std::vector<odtone::mih::threshold> thl; - odtone::mih::link_tuple_id lti; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - //List of the link threshold parameters - odtone::mih::link_cfg_param_list lcpl; - odtone::mih::link_cfg_param lcp; - odtone::mih::link_param_lte lp; - //odtone::mih::link_param_gen lp; - - odtone::mih::link_param_type typr; - - log_(0,""); - log_(0, "send_MIH_Link_Configure_Thresholds_request - Begin"); - - //link_tuple_id - lti.type = rcv_link_id.type; - lti.addr = rcv_link_id.addr; - - //local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(lti.addr); - - - //link_param_gen_data_rate = 0, /**< Data rate. */ - //link_param_gen_signal_strength = 1, /**< Signal strength. */ - //link_param_gen_sinr = 2, /**< SINR. */ - //link_param_gen_throughput = 3, /**< Throughput. */ - //link_param_gen_packet_error_rate = 4, /**< Packet error rate. */ - //lp = odtone::mih::link_param_lte_bandwidth; - lp = odtone::mih::link_param_lte_rsrp; - lcp.type = lp; - - link_measures_request = 0; - if ( link_measures_request ==0){ - // Set Timer Interval (in ms) - lcp.timer_interval = 3000; - //th_action_normal = 0, /**< Set normal threshold. */ - //th_action_one_shot = 1, /**< Set one-shot threshold. */ - //th_action_cancel = 2 /**< Cancel threshold. */ - lcp.action = odtone::mih::th_action_normal; - link_measures_request = 1; - } else if ( link_measures_request==1){ - // Set Timer Interval (in ms) - lcp.timer_interval = 0; - lcp.action = odtone::mih::th_action_cancel; - link_measures_request = 0; - } - - //above_threshold = 0, /**< Above threshold. */ - //below_threshold = 1, /**< Below threshold. */ - th.threshold_val = -105; - th.threshold_x_dir = odtone::mih::threshold::above_threshold; - - thl.push_back(th); - lcp.threshold_list = thl; - lcpl.push_back(lcp); - - m << odtone::mih::request(odtone::mih::request::link_configure_thresholds) - & odtone::mih::tlv_link_identifier(lti) - & odtone::mih::tlv_link_cfg_param_list(lcpl); - - m.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihuserid.to_string() +"][--- MIH_Link_Configure_Thresholds.request\\nlink="+ - // link_tupple_id2string(lti).c_str() + - link_id2string(lti).c_str()+ - " --->]["+_mihfid.to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::event_handler, this, _1, _2)); - - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(lti).c_str()); - - log_(0, "\t- LINK CFG PARAM LIST - Length: ", lcpl.size()); - - //if(lp == odtone::mih::link_param_gen_data_rate) {log_(0, "\t Generic link parameter DATA RATE ");} - //if(lp == odtone::mih::link_param_gen_signal_strength) {log_(0, "\t Generic link parameter SIGNAL STRENGTH");} - //if(lp == odtone::mih::link_param_gen_sinr) {log_(0, "\t Generic link parameter SINR");} - //if(lp == odtone::mih::link_param_gen_throughput) {log_(0, "\t Generic link parameter THROUGHPUT");} - //if(lp == odtone::mih::link_param_lte_bandwidth) {log_(0, "\t LTE link parameter BANDWIDTH");} - if(lp == odtone::mih::link_param_lte_rsrp) {log_(0, "\t LTE link parameter LTE RSRP");} - - log_(0, "\t- TIMER INTERVAL - Value: ", lcp.timer_interval); - - if(lcp.action == odtone::mih::th_action_normal) {log_(0, "\t Normal Threshold");} - if(lcp.action == odtone::mih::th_action_one_shot) {log_(0, "\t One Shot Threshold");} - if(lcp.action == odtone::mih::th_action_cancel) {log_(0, "\t Threshold to be canceled");} - - log_(0, "\t Threshold value: ", th.threshold_val); - - if(th.threshold_x_dir == odtone::mih::threshold::below_threshold) {log_(0, "\t Threshold direction BELOW");} - if(th.threshold_x_dir == odtone::mih::threshold::above_threshold) {log_(0, "\t Threshold direction ABOVE");} - - log_(0, "send_MIH_Link_Configure_Thresholds_request - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Configure_Thresholds_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - log_(0, ""); - log_(0, "receive_MIH_Link_Configure_Thresholds_confirm - Begin"); - - // T odtone::uint iter; - // T odtone::mih::status st; - - //boost::optional<odtone::mih::link_cfg_status_list> lcsl; - // Todtone::mih::link_cfg_status_list lcsl; - // Todtone::mih::link_cfg_status lcp; - //odtone::mih::link_param_gen lp; - - // T odtone::mih::link_tuple_id lti; - - //msg >> odtone::mih::confirm() - // & odtone::mih::tlv_status(st) - // & odtone::mih::tlv_link_identifier(lti) - // & odtone::mih::tlv_link_cfg_status_list(lcsl); - - - log_(0, "receive_MIH_Link_Configure_Thresholds_confirm - End"); - log_(0,""); -} - -//----------------------------------------------------------------------------- -int main(int argc, char** argv) -//----------------------------------------------------------------------------- -{ - odtone::setup_crash_handler(); - - try { - boost::asio::io_service ios; - - // declare MIH Usr available options - po::options_description desc(odtone::mih::octet_string("MIH Usr Configuration")); - desc.add_options() - ("help", "Display configuration options") - (odtone::sap::kConf_File, po::value<std::string>()->default_value("ue_lte_user.conf"), "Configuration file") - (odtone::sap::kConf_Receive_Buffer_Len, po::value<uint>()->default_value(4096), "Receive buffer length") - (odtone::sap::kConf_Port, po::value<ushort>()->default_value(1235), "Listening port") - (odtone::sap::kConf_MIH_SAP_id, po::value<std::string>()->default_value("user"), "MIH-User ID") - (kConf_MIH_Commands, po::value<std::string>()->default_value(""), "MIH-User supported commands") - (odtone::sap::kConf_MIHF_Ip, po::value<std::string>()->default_value("127.0.0.1"), "Local MIHF IP address") - (odtone::sap::kConf_MIHF_Local_Port, po::value<ushort>()->default_value(1025), "Local MIHF communication port") - (odtone::sap::kConf_MIH_SAP_dest, po::value<std::string>()->default_value("mihf2_ue"), "MIHF destination"); - - odtone::mih::config cfg(desc); - cfg.parse(argc, argv, odtone::sap::kConf_File); - - if (cfg.help()) { - std::cerr << desc << std::endl; - return EXIT_SUCCESS; - } - - mih_user usr(cfg, ios); - - ios.run(); - - } catch(std::exception& e) { - log_(0, "exception: ", e.what()); - } -} - -// EOF //////////////////////////////////////////////////////////////////////// - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/Makefile b/openair3/RAL-LTE/LTE_RAL_UE/Makefile deleted file mode 100755 index 6cc42a2229..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/Makefile +++ /dev/null @@ -1,75 +0,0 @@ -# lines starting with the pound sign are comments. -# -# These things are options that you might need -# to tweak. - - - -INTERFACE_DIR=../INTERFACE-802.21 -INCLUDE_DIR=INCLUDE -SRC_DIR=SRC -# external directories for ioctl -RRC_DIR := $(OPENAIR2_DIR)/RRC/CELLULAR -NAS_DIR := $(OPENAIR2_DIR)/NAS/DRIVER/CELLULAR/NASMT - -# SVN version -#SVNREV = -D'SVN_REV="$(shell svnversion -n .)"' -SVNREV = -D'SVN_REV="1"' - -CC = gcc - -#CFLAGS = -Wall -g -I$(SRC_DIR) -I$(INTERFACE_DIR)/INCLUDE -I$(INCLUDE_DIR) \ -# -DMIH_C_MEDIEVAL_EXTENSIONS -DMSCGEN_PYTOOL -DMIH_USER_CONTROL $(SVNREV) - -CFLAGS = -Wall -g -I$(SRC_DIR) -I$(INTERFACE_DIR)/INCLUDE -I$(INCLUDE_DIR) -DMIH_C_MEDIEVAL_EXTENSIONS -DMIH_USER_CONTROL $(SVNREV) -CFLAGS += -I$(NAS_DIR) -I$(RRC_DIR) - -LDFLAGS = -L$(INTERFACE_DIR)/LIB -lmih_c-802.21 -lrt - -MRAL_OBJS = $(SRC_DIR)/lteRALue_mih_msg.o -#MRAL_OBJS += $(SRC_DIR)/lteRALue_thresholds.o -#MRAL_OBJS += $(SRC_DIR)/lteRALue_parameters.o -#MRAL_OBJS += $(SRC_DIR)/lteRALue_action.o -#MRAL_OBJS += $(SRC_DIR)/lteRALue_get.o -#MRAL_OBJS += $(SRC_DIR)/lteRALue_subscribe.o -MRAL_OBJS += $(SRC_DIR)/lteRALue_mih_execute.o -MRAL_OBJS += $(SRC_DIR)/lteRALue_main.o -MRAL_OBJS += $(SRC_DIR)/lteRALue_ioctl.o -MRAL_OBJS += $(SRC_DIR)/lteRALue_process.o - - -OBJS = $(MRAL_OBJS) - -M_RAL_EXE = LTE_RAL_UE - -EXECUTABLE = interface $(M_RAL_EXE) - -# "all" is the default target. Simply make it point to myprogram. - -all: $(EXECUTABLE) - -runral: $(M_RAL_EXE) - -rm -f /tmp/*.txt - -./$(M_RAL_EXE) > /tmp/mral.txt - -interface : - -(cd $(INTERFACE_DIR) && make) -# -(cd $(INTERFACE_DIR) && make clean && make) - -cleaninterface : - -(cd $(INTERFACE_DIR) && make clean) - - -$(M_RAL_EXE) : $(MRAL_OBJS) - $(CC) -o $@ $^ $(LDFLAGS) - -%.o: %.c Makefile - @echo Compiling $< - @$(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) -o $@ $< - -clean: - -find . -name "*.o" -delete - -find . -name "*.*~" -delete - -find . -name "*~" -delete -# -rm -f $(M_RAL_EXE) $(M_NAS_EXE) -# -rm -f $(E_RAL_EXE) $(E_NAS_EXE) diff --git a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_action.c b/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_action.c deleted file mode 100755 index a522369b1d..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_action.c +++ /dev/null @@ -1,240 +0,0 @@ -/*************************************************************************** - lteRALue_action.c - description - *************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 1999 - 2013 Eurecom - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information - Openair Admin: openair_admin@eurecom.fr - Openair Tech : openair_tech@eurecom.fr - Forums : http://forums.eurecom.fsr/openairinterface - Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France -*******************************************************************************/ -/*! \file lteRALue_mih_execute.c - * \brief Execution of MIH primitives in LTE-RAL-UE - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#define LTE_RAL_UE -#define LTERALUE_ACTION_C -//----------------------------------------------------------------------------- -#include "lteRALue.h" -#include "LAYER2/MAC/extern.h" - -//----------------------------------------------------------------------------- -void mRAL_action_request(ral_ue_instance_t instanceP, MIH_C_Message_Link_Action_request_t* messageP) -{ - //----------------------------------------------------------------------------- - MIH_C_STATUS_T status; - LIST(MIH_C_LINK_SCAN_RSP, scan_response_set); - MIH_C_LINK_AC_RESULT_T link_action_result; - //unsigned int scan_index, meas_to_send; - MessageDef *message_p = NULL; - rrc_ral_connection_release_req_t release_req; - rrc_ral_connection_establishment_req_t connection_establishment_req; - module_id_t mod_id = instanceP - NB_eNB_INST; - - status = MIH_C_STATUS_SUCCESS; - link_action_result = MIH_C_LINK_AC_RESULT_SUCCESS; - scan_response_set_list.length = 0; - - if ( messageP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_LINK_SCAN) { - //---------------------------------------------------- - // send a response to MIH-F or it will report an error. - //---------------------------------------------------- - //link_action_result = MIH_C_LINK_AC_RESULT_SUCCESS; - //mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - - //---------------------------------------------------- - // Transmit request to RRC. - //---------------------------------------------------- - message_p = itti_alloc_new_message (TASK_RAL_UE, RRC_RAL_SCAN_REQ); - RRC_RAL_SCAN_REQ(message_p).transaction_id = messageP->header.transaction_id; - itti_send_msg_to_task (TASK_RRC_UE, instanceP, message_p); - } - - if ( messageP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_LINK_RES_RETAIN) { - // TO DO - // The link will be disconnected but the resource for the link connection still remains so - // reestablishing the link connection later can be more efficient. - - } - - if ( messageP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_DATA_FWD_REQ) { - // TO DO - // This indication requires the buffered data at the old serving PoA entity to be forwarded - // to the new target PoA entity in order to avoid data loss. This action can be taken imme- - // diately after the old serving PoS receives MIH_N2N_HO_Commit response message - // from the new target PoS, or the old serving PoS receives MIH_Net_HO_Commit - // response message from the MN. This is not valid on UMTS link type. - - } - - // do not make actions if SCAN required - if (( messageP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_LINK_SCAN) == 0) { - switch (messageP->primitive.LinkAction.link_ac_type) { - case MIH_C_LINK_AC_TYPE_NONE: - LOG_D(RAL_UE, "%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_NONE: NO ACTION\n", __FUNCTION__); - break; - - case MIH_C_LINK_AC_TYPE_LINK_DISCONNECT: - LOG_D(RAL_UE, "%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_DISCONNECT: NO ACTION\n", __FUNCTION__); - - if (g_ue_ral_obj[mod_id].mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_DISCONNECT) { - message_p = itti_alloc_new_message (TASK_RAL_UE, RRC_RAL_CONNECTION_RELEASE_REQ); - memset(&release_req, 0, sizeof(rrc_ral_connection_release_req_t)); - // copy transaction id - release_req.transaction_id = messageP->header.transaction_id; - memcpy (&message_p->ittiMsg, (void *) &release_req, sizeof(rrc_ral_connection_release_req_t)); - itti_send_msg_to_task (TASK_RRC_UE, instanceP, message_p); - } else { - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - - break; - - case MIH_C_LINK_AC_TYPE_LINK_LOW_POWER: - LOG_D(RAL_UE, "%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_LOW_POWER\n", __FUNCTION__); - - if (g_ue_ral_obj[mod_id].mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_LOW_POWER) { - // TO DO - } else { - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - - break; - - case MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN: - LOG_D(RAL_UE, "%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN\n", __FUNCTION__); - - if (g_ue_ral_obj[mod_id].mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN) { - if ( g_ue_ral_obj[mod_id].pending_req_action & MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN ) { - if (g_ue_ral_obj[mod_id].state == DISCONNECTED) { - LOG_D(RAL_UE, "Deactivation requested, but interface already inactive ==> NO OP\n"); - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } else { - g_ue_ral_obj[mod_id].pending_req_action = g_ue_ral_obj[mod_id].pending_req_action | MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN; - //Send immediatly a confirm, otherwise it will arrive to late and MIH-F will report a failure to the MIH-USER - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, NULL, &link_action_result); - - message_p = itti_alloc_new_message (TASK_RAL_UE, RRC_RAL_CONNECTION_RELEASE_REQ); - memset(&release_req, 0, sizeof(rrc_ral_connection_release_req_t)); - // copy transaction id - release_req.transaction_id = messageP->header.transaction_id; - memcpy (&message_p->ittiMsg, (void *) &release_req, sizeof(rrc_ral_connection_release_req_t)); - itti_send_msg_to_task (TASK_RRC_UE, instanceP, message_p); - LOG_D(RAL_UE, "Deactivation requested to NAS interface\n"); - //RAL_process_NAS_message(IO_OBJ_CNX, IO_CMD_DEL, g_ue_ral_obj[mod_id].cell_id); - - } - } else { - g_ue_ral_obj[mod_id].pending_req_action |= MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN; - //Send immediatly a confirm, otherwise it will arrive to late and MIH-F will report a failure to the MIH-USER - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, NULL, &link_action_result); - - message_p = itti_alloc_new_message (TASK_RAL_UE, RRC_RAL_CONNECTION_RELEASE_REQ); - memset(&release_req, 0, sizeof(rrc_ral_connection_release_req_t)); - // copy transaction id - release_req.transaction_id = messageP->header.transaction_id; - memcpy (&message_p->ittiMsg, (void *) &release_req, sizeof(rrc_ral_connection_release_req_t)); - itti_send_msg_to_task (TASK_RRC_UE, instanceP, message_p); - LOG_D(RAL_UE, "Deactivation requested to NAS interface\n"); - //RAL_process_NAS_message(IO_OBJ_CNX, IO_CMD_DEL, g_ue_ral_obj[mod_id].cell_id); - } - } else { - LOG_D(RAL_UE, " command POWER DOWN not available \n\n"); - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, NULL, &link_action_result); - } - - break; - - case MIH_C_LINK_AC_TYPE_LINK_POWER_UP: - LOG_D(RAL_UE, "%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_POWER_UP\n", __FUNCTION__); - - if (g_ue_ral_obj[mod_id].mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_POWER_UP) { - // Activation requested - check it is not already active - if(g_ue_ral_obj[mod_id].pending_req_action & MIH_C_LINK_AC_TYPE_LINK_POWER_UP) { - if (g_ue_ral_obj[mod_id].state == CONNECTED) { - LOG_D(RAL_UE, "Activation requested, but interface already active ==> NO OP\n"); - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } else { - g_ue_ral_obj[mod_id].pending_req_action = g_ue_ral_obj[mod_id].pending_req_action | MIH_C_LINK_AC_TYPE_LINK_POWER_UP; - g_ue_ral_obj[mod_id].cell_id = g_ue_ral_obj[mod_id].meas_cell_id[0]; // Default cell #0 - Next, choose cell with best conditions - LOG_D(RAL_UE, "Activation requested to NAS interface on cell %d\n", g_ue_ral_obj[mod_id].cell_id); - //RAL_process_NAS_message(IO_OBJ_CNX, IO_CMD_ADD, g_ue_ral_obj[mod_id].cell_id); - } - } else { - g_ue_ral_obj[mod_id].pending_req_action |= MIH_C_LINK_AC_TYPE_LINK_POWER_UP; - g_ue_ral_obj[mod_id].cell_id = g_ue_ral_obj[mod_id].meas_cell_id[0]; // Default cell #0 - Next, choose cell with best conditions - message_p = itti_alloc_new_message (TASK_RAL_UE, RRC_RAL_CONNECTION_ESTABLISHMENT_REQ); - memset(&connection_establishment_req, 0, sizeof(rrc_ral_connection_establishment_req_t)); - // copy transaction id - connection_establishment_req.transaction_id = messageP->header.transaction_id; - memcpy (&message_p->ittiMsg, (void *) &connection_establishment_req, sizeof(rrc_ral_connection_establishment_req_t)); - itti_send_msg_to_task (TASK_RRC_UE, instanceP, message_p); - } - } else { - LOG_D(RAL_UE, "[mRAL]: command POWER UP not available \n\n"); - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - - break; - - /* LG KEEP case MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR: - LOG_D(RAL_UE, "%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR: NO ACTION\n", __FUNCTION__); - if (g_ue_ral_obj[mod_id].mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR) { - } else { - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - break; - - case MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES: - LOG_D(RAL_UE, "%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES: NO ACTION\n", __FUNCTION__); - if (g_ue_ral_obj[mod_id].mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES) { - } else { - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - break; - - case MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES: - LOG_D(RAL_UE, "%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES: NO ACTION\n", __FUNCTION__); - if (g_ue_ral_obj[mod_id].mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES) { - } else { - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - break;*/ - - default: - LOG_E(RAL_UE, "%s Invalid LinkAction.link_ac_type in MIH_C_Message_Link_Action_request\n", __FUNCTION__); - status = MIH_C_STATUS_UNSPECIFIED_FAILURE; - mRAL_send_link_action_confirm(instanceP, &messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - } -} - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_ioctl.c b/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_ioctl.c deleted file mode 100755 index bedf47015d..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_ioctl.c +++ /dev/null @@ -1,455 +0,0 @@ -/*************************************************************************** - lteRALue_ioctl.c - description - *************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 1999 - 2013 Eurecom - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information - Openair Admin: openair_admin@eurecom.fr - Openair Tech : openair_tech@eurecom.fr - Forums : http://forums.eurecom.fsr/openairinterface - Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France -*******************************************************************************/ -/*! \file lteRALue_ioctl.c - * \brief Handling of ioctl for LTE driver in LTE-RAL-UE - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#define MRAL_MODULE -#include "rrc_d_types.h" -#include "nas_ue_ioctl.h" -#include "rrc_nas_primitives.h" -#include "nasmt_constant.h" -#include "nasmt_iocontrol.h" - -#include "lteRALue_mih_msg.h" -#include "lteRALue_variables.h" -#include "lteRALue_proto.h" -#include "MIH_C.h" -#include "lteRALue_mih_msg.h" - -extern struct nas_ioctl gifr; -extern int fd; -// 0335060080149150 -uint8_t NAS_DEFAULT_IMEI[16]= {0x00, 0x03, 0x03, 0x05, 0x00 ,0x06, 0x00, 0x00, 0x08, 0x00, 0x01 ,0x04, 0x09, 0x01, 0x05, 0x00}; - -//--------------------------------------------------------------------------- -void print_state(uint8_t state) -{ - //--------------------------------------------------------------------------- - switch(state) { - case NAS_IDLE: - DEBUG("NAS_IDLE\n"); - return; - - // case NAS_STATE_CONNECTED:DEBUG("NAS_STATE_CONNECTED\n");return; - // case NAS_STATE_ESTABLISHMENT_REQUEST:DEBUG("NAS_STATE_ESTABLISHMENT_REQUEST\n");return; - // case NAS_STATE_ESTABLISHMENT_FAILURE:DEBUG("NAS_STATE_ESTABLISHMENT_FAILURE\n");return; - // case NAS_STATE_RELEASE_FAILURE:DEBUG("NAS_STATE_RELEASE_FAILURE\n");return; - case NAS_CX_FACH: - DEBUG("NAS_CX_FACH\n"); - return; - - case NAS_CX_DCH: - DEBUG("NAS_CX_DCH\n"); - return; - - case NAS_CX_RECEIVED: - DEBUG("NAS_CX_RECEIVED\n"); - return; - - case NAS_CX_CONNECTING: - DEBUG("NAS_CX_CONNECTING\n"); - return; - - case NAS_CX_RELEASING: - DEBUG("NAS_CX_RELEASING\n"); - return; - - case NAS_CX_CONNECTING_FAILURE: - DEBUG("NAS_CX_CONNECTING_FAILURE\n"); - return; - - case NAS_CX_RELEASING_FAILURE: - DEBUG("NAS_CX_RELEASING_FAILURE\n"); - return; - - case NAS_RB_ESTABLISHING: - DEBUG("NAS_RB_ESTABLISHING\n"); - return; - - case NAS_RB_RELEASING: - DEBUG("NAS_RB_RELEASING\n"); - return; - - case NAS_RB_DCH: - DEBUG("NAS_RB_DCH\n"); - return; - - default: - ERR(" Unknown state\n"); - } -} - - -//--------------------------------------------------------------------------- -// Convert the IMEI to iid -void RAL_imei2iid(uint8_t *imei, uint8_t *iid) -{ - //--------------------------------------------------------------------------- - // Start debug information - if (!imei ||! iid ) { - ERR("RAL_imei2iid - input parameter is NULL \n"); - return; - } - - // End debug information - memset(iid, 0, 8); - iid[0] = 16*imei[0]+imei[1]; - iid[1] = 16*imei[2]+imei[3]; - iid[2] = 16*imei[4]+imei[5]; - iid[3] = 16*imei[6]+imei[7]; - iid[4] = 16*imei[8]+imei[9]; - iid[5] = 16*imei[10]+imei[11]; - iid[6] = 16*imei[12]+imei[13]; - iid[7] = 16*imei[14]+imei[15]+1; -} - -//--------------------------------------------------------------------------- -int RAL_process_NAS_message(int ioctl_obj, int ioctl_cmd, int ioctl_cellid) -{ - //--------------------------------------------------------------------------- - int err, rc; - - NOTICE(" \n"); - - switch (ioctl_obj) { - /***************************/ - case IO_OBJ_STATS: { - struct nas_msg_statistic_reply *msgrep; - - //printf("Statistics requested -0\n"); - gifr.type=NAS_MSG_STATISTIC_REQUEST; - // gifr.msg=(char *)malloc(sizeof(struct nas_msg_statistic_reply)); - memset (ralpriv->buffer,0,800); - gifr.msg= &(ralpriv->buffer[0]); - msgrep=(struct nas_msg_statistic_reply *)(gifr.msg); - NOTICE("[MSC_MSG][%s][%s][--- ioctl : NAS_MSG_STATISTIC_REQUEST --->][nas]\n", getTimeStamp4Log(), g_link_id); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } else { - DEBUG("tx_packets = %u, rx_packets = %u\n", msgrep->tx_packets, msgrep->rx_packets); - DEBUG("tx_bytes = %u, rx_bytes = %u\n", msgrep->tx_bytes, msgrep->rx_bytes); - DEBUG("tx_errors = %u, rx_errors = %u\n", msgrep->tx_errors, msgrep->rx_errors); - DEBUG("tx_dropped = %u, rx_dropped = %u\n", msgrep->tx_dropped, msgrep->rx_dropped); - memcpy(&(ralpriv->rx_packets), &(msgrep->rx_packets), sizeof(struct nas_msg_statistic_reply)); - //IAL_return_NAS_Statistics(); - rc = 0; - } - } - break; - - /***************************/ - case IO_OBJ_CNX: - switch (ioctl_cmd) { - /***/ - case IO_CMD_ADD: { - //printf("Usage: gioctl cx add <lcr> <cellid>\n"); - struct nas_msg_cx_establishment_request *msgreq; - struct nas_msg_cx_establishment_reply *msgrep; - gifr.type=NAS_MSG_CX_ESTABLISHMENT_REQUEST; - //gifr.msg=(char *)malloc(sizeof(msgrep)<sizeof(msgreq)?sizeof(msgreq):sizeof(msgrep)); - memset (ralpriv->buffer,0,800); - gifr.msg= &(ralpriv->buffer[0]); - msgreq=(struct nas_msg_cx_establishment_request *)(gifr.msg); - msgrep=(struct nas_msg_cx_establishment_reply *)(gifr.msg); - msgreq->lcr=0; //Temp <lcr> - msgreq->cellid=ioctl_cellid; - // send IOCTL - NOTICE("[MSC_MSG][%s][%s][--- ioctl : NAS_MSG_CX_ESTABLISHMENT_REQUEST --->][nas]\n", getTimeStamp4Log(), g_link_id); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - ERR("IOCTL error, err=%d\n",err); - } - - NOTICE("[MSC_MSG][%s][nas][--- NAS_MSG_CX_ESTABLISHMENT_REPLY --->][%s]\n", getTimeStamp4Log(), g_link_id); - ralpriv->pending_req_action = MIH_C_LINK_AC_TYPE_NONE; - ralpriv->state = DISCONNECTED; - - if ((err<0)||(msgrep->status<0)) { - ERR(" Connexion establishment failure: %d\n",msgrep->status); - //ralpriv->state = DISCONNECTED; - rc = -1; - ralpriv->pending_req_status = MIH_C_STATUS_SUCCESS; - ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_FAILURE; - } else { - //ralpriv->state = CONNECTED; - ralpriv->cell_id = ioctl_cellid; - ralpriv->pending_req_status = MIH_C_STATUS_SUCCESS; - ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_SUCCESS; - ralpriv->pending_req_flag = 1; - DEBUG(" Connexion establishment pending: pending_req_flag %d\n",ralpriv->pending_req_flag); - } - - //mRAL_send_link_action_confirm(&ralpriv->pending_req_transaction_id, &ralpriv->pending_req_status, NULL, &ralpriv->pending_req_ac_result); - rc = 0; - } - break; - - /***/ - case IO_CMD_DEL: { - //printf("Usage: gioctl cx del <lcr>\n"); - struct nas_msg_cx_release_request *msgreq; - struct nas_msg_cx_release_reply *msgrep; - gifr.type=NAS_MSG_CX_RELEASE_REQUEST; - //gifr.msg=(char *)malloc(sizeof(msgrep)<sizeof(msgreq)?sizeof(msgreq):sizeof(msgrep)); - memset (ralpriv->buffer,0,800); - gifr.msg= &(ralpriv->buffer[0]); - msgreq=(struct nas_msg_cx_release_request *)(gifr.msg); - msgrep=(struct nas_msg_cx_release_reply *)(gifr.msg); - msgreq->lcr=0; //Temp <lcr> - // - NOTICE("[MSC_MSG][%s][%s][--- ioctl : NAS_MSG_CX_RELEASE_REQUEST --->][nas]\n", getTimeStamp4Log(), g_link_id); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } - - // - NOTICE("[MSC_MSG][%s][nas][--- NAS_MSG_CX_RELEASE_REPLY --->][%s]\n", getTimeStamp4Log(), g_link_id); - ralpriv->pending_req_action = MIH_C_LINK_AC_TYPE_NONE; - - if (msgrep->status<0) { - ERR(" Connexion release failure: %d", msgrep->status); - rc = -1; - } - - if (rc == -1) { // something failed - ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_FAILURE; - } else { - ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_SUCCESS; - } - - ralpriv->pending_req_status = MIH_C_STATUS_SUCCESS; - ralpriv->state = DISCONNECTED; - //mRALu_send_link_switch_cnf(); - ralpriv->pending_req_flag = 0; - ralpriv->cell_id = CONF_UNKNOWN_CELL_ID; - rc = 0; - } - break; - - /***/ - case IO_CMD_LIST: { - //printf("Usage: gioctl cx list\n"); - uint8_t *msgrep; - uint8_t i; - struct nas_msg_cx_list_reply *list; - uint8_t lcr; - gifr.type=NAS_MSG_CX_LIST_REQUEST; - //gifr.msg=(char *)malloc(NAS_LIST_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1); - memset (ralpriv->buffer,0,800); - gifr.msg= &(ralpriv->buffer[0]); - msgrep=(uint8_t *)(gifr.msg); - // - NOTICE("[MSC_MSG][%s][%s][--- ioctl : NAS_MSG_CX_LIST_REQUEST --->][nas]\n", getTimeStamp4Log(), g_link_id); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } else { - NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_CNX_LIST_REPLY --->][%s]\n", getTimeStamp4Log(), g_link_id); - DEBUG("Lcr\t\tCellId\tIID4\tIID6\t\t\tnum_rb\tnsclass\tState\n"); - list=(struct nas_msg_cx_list_reply *)(msgrep+1); - lcr=0; - DEBUG("%u\t\t%u\t%u\t", list[lcr].lcr, list[lcr].cellid, list[lcr].iid4); - - for (i=0; i<8; ++i) - DEBUG("%02x", *((uint8_t *)list[lcr].iid6+i)); - - DEBUG("\t%u\t%u\t", list[lcr].num_rb, list[lcr].nsclassifier); - print_state(list[lcr].state); - - ralpriv->nas_state = list[lcr].state ; - ralpriv->num_rb = list[lcr].num_rb; - ralpriv->num_class = list[lcr].nsclassifier; - ralpriv->cell_id = list[lcr].cellid ; - //IAL_return_NAS_StatAttach(); - rc = 0; - } - } - break; - - /***/ - default: - ERR ("IAL_process_NAS_message : IO_OBJ_CNX : invalid ioctl command %d\n",ioctl_cmd); - rc= -1; - } //end switch ioctl_cmd - - break; - - /***************************/ - case IO_OBJ_RB: - switch (ioctl_cmd) { - /***/ - case IO_CMD_LIST: { - //printf("Usage: gioctl rb list <lcr>\n"); - uint8_t *msgrep; - uint8_t rbi; - struct nas_msg_rb_list_reply *list; - struct nas_msg_rb_list_request *msgreq; - gifr.type=NAS_MSG_RB_LIST_REQUEST; - // gifr.msg=(char *)malloc(NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1); - memset (ralpriv->buffer,0,800); - gifr.msg= &(ralpriv->buffer[0]); - msgreq=(struct nas_msg_rb_list_request *)(gifr.msg); - msgrep=(uint8_t *)(gifr.msg); - msgreq->lcr=0; //Temp <lcr> - MT - // - NOTICE("[MSC_MSG][%s][%s][--- ioctl : NAS_MSG_RB_LIST_REQUEST --->][nas]\n", getTimeStamp4Log(), g_link_id); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } else { - DEBUG("rab_id\t\tSapi\t\tQoS\t\tState\n"); - list=(struct nas_msg_rb_list_reply *)(msgrep+1); - - for (rbi=0; rbi<msgrep[0]; ++rbi) { - DEBUG("%u\t\t%u\t\t%u\t\t", list[rbi].rab_id, list[rbi].sapi, list[rbi].qos); - print_state(list[rbi].state); - rc = 0; - } - - // - ralpriv->num_rb = msgrep[0]; - - for (rbi=0; rbi<ralpriv->num_rb; rbi++) { - ralpriv->rbId[rbi]= list[rbi].rab_id; - ralpriv->QoSclass[rbi] = list[rbi].qos; - ralpriv->dscp[rbi] = rbi+4; - } - - //IAL_return_NAS_StatRB(); - } - } - break; - - /***/ - default: - ERR ("IAL_process_NAS_message : IO_OBJ_RB : invalid ioctl command %d\n",ioctl_cmd); - rc= -1; - } //end switch ioctl_cmd - - break; - - /***************************/ - case IO_OBJ_MEAS: - // - { - uint8_t i; - struct nas_msg_measure_request *msgreq; - struct nas_msg_measure_reply *msgrep; - gifr.type=NAS_MSG_MEAS_REQUEST; - // gifr.msg=(char *)malloc(sizeof(msgrep)<sizeof(msgreq)?sizeof(msgreq):sizeof(msgrep)); - memset (ralpriv->buffer,0,800); - gifr.msg= &(ralpriv->buffer[0]); - msgreq=(struct nas_msg_measure_request *)(gifr.msg); - msgrep=(struct nas_msg_measure_reply *)(gifr.msg); - // - NOTICE("[MSC_MSG][%s][%s][--- ioctl : NAS_MSG_MEAS_REQUEST --->][nas]\n", getTimeStamp4Log(), g_link_id); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - ERR("IOCTL error, err=%d\n",err); - rc = -1; - } else { - // - NOTICE("[MSC_MSG][%s][nas][--- NAS_MSG_MEAS_REPLY --->][%s]\n", getTimeStamp4Log(), g_link_id); - - // ralpriv->num_measures = msgrep->num_cells; TEMP- To be activated later - for (i=0; i<msgrep->num_cells; i++) { - ralpriv->meas_cell_id[i] = msgrep-> measures[i].cell_id; - IAL_integrate_measure(msgrep-> measures[i].level, i); - ralpriv->provider_id[i] = msgrep-> measures[i].provider_id; - } - - DEBUG("Measurement Report - Number of cells %d - Current cell %d\n", msgrep->num_cells, ralpriv->cell_id); -#ifdef DEBUG_MRALU_MEASURES - DEBUG("Cell_id\tMeasure\tProvider_id\n"); - - for (i=0; i<msgrep->num_cells; i++) { - DEBUG(" %d\t%d\t%d\n",msgrep-> measures[i].cell_id,msgrep-> measures[i].level,msgrep-> measures[i].provider_id); - } - -#endif - //Temp - //ralpriv->meas_cell_id[0] = ralpriv->cell_id; - rc = 0; - } - } - break; - - /***************************/ - case IO_OBJ_IMEI: { - struct nas_msg_l2id_reply *msgrep; - gifr.type=NAS_MSG_IMEI_REQUEST; - // gifr.msg=(char *)malloc(sizeof(struct nas_msg_statistic_reply)); - memset (ralpriv->buffer,0,800); - gifr.msg= &(ralpriv->buffer[0]); - msgrep=(struct nas_msg_l2id_reply *)(gifr.msg); - NOTICE("[MSC_MSG][%s][%s][--- ioctl : NAS_MSG_IMEI_REQUEST (L2Id) --->][nas]\n", getTimeStamp4Log(), g_link_id); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - ERR("IOCTL error, err=%d\n",err); - rc = -1; - // default IMEI address : NAS_DEFAULT_IMEI - RAL_imei2iid(NAS_DEFAULT_IMEI, (uint8_t *)&(ralpriv->ipv6_l2id[0])); - } else { - NOTICE("[MSC_MSG][%s][nas][--- NAS_MSG_IMEI_REPLY --->][%s]\n", getTimeStamp4Log(), g_link_id); - DEBUG("IMEI value received= %d %d\n", msgrep->l2id[0], msgrep->l2id[1]); - //store the received value, to be used later - ralpriv->ipv6_l2id[0] = msgrep->l2id[0]; - ralpriv->ipv6_l2id[1] = msgrep->l2id[1]; - rc = 0; - } - } - break; - - /***************************/ - default: - ERR ("IAL_process_NAS_message : invalid ioctl object %d\n",ioctl_obj); - rc= -1; - } //end switch ioctl_obj - - return rc; -} - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_main.c b/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_main.c deleted file mode 100755 index 2448d08283..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_main.c +++ /dev/null @@ -1,375 +0,0 @@ -/*************************************************************************** - lteRALue_main.c - description - *************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 1999 - 2013 Eurecom - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information - Openair Admin: openair_admin@eurecom.fr - Openair Tech : openair_tech@eurecom.fr - Forums : http://forums.eurecom.fsr/openairinterface - Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France -*******************************************************************************/ -/*! \file lteRALue_main.c - * \brief This file contains the main() function for the LTE-RAL-UE - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#define LTE_RAL_UE -#define LTERALUE_MAIN_C -//----------------------------------------------------------------------------- -#include <stdio.h> -# include <sys/epoll.h> -#include <sys/select.h> -#include <net/if.h> -#include <getopt.h> -#include <stdlib.h> -#include <time.h> -//----------------------------------------------------------------------------- -#include "assertions.h" -#include "lteRALue.h" -#include "LAYER2/MAC/extern.h" -#include "intertask_interface.h" -#include "OCG.h" -//----------------------------------------------------------------------------- - -extern unsigned char NB_eNB_INST; -extern unsigned char NB_UE_INST; -extern OAI_Emulation oai_emulation; - - -//--------------------------------------------------------------------------- -void mRAL_get_IPv6_addr(void) -{ - //--------------------------------------------------------------------------- -#define IPV6_ADDR_LINKLOCAL 0x0020U - -#ifdef RAL_DUMMY - char * eth0_name="eth0";/* interface name */ -#endif -#ifdef RAL_REALTIME - char * graal0_name="oai0";/* interface name */ -#endif - - FILE *f; - char devname[20]; - int plen, scope, dad_status, if_idx; - char addr6p[8][5]; - int intf_found = 0; - char my_addr[16]; - char temp_addr[32]; - int i, j; - - if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) { - while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], - addr6p[4], addr6p[5], addr6p[6], addr6p[7], - &if_idx, &plen, &scope, &dad_status, devname) != EOF) { -#ifdef RAL_DUMMY - - if (!strcmp(devname, eth0_name)) { -#endif -#ifdef RAL_REALTIME - - if (!strcmp(devname, graal0_name)) { -#endif - intf_found = 1; - - // retrieve numerical value - if ((scope ==0)||(scope== IPV6_ADDR_LINKLOCAL)) { - LOG_D(RAL_UE, " adresse %s:%s:%s:%s:%s:%s:%s:%s", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], - addr6p[4], addr6p[5], addr6p[6], addr6p[7]); - LOG_D(RAL_UE, " Scope:"); - - switch (scope) { - case 0: - LOG_D(RAL_UE, "Global"); - break; - - case IPV6_ADDR_LINKLOCAL: - LOG_D(RAL_UE, "Link"); - break; - - default: - LOG_D(RAL_UE, "Unknown"); - } - - LOG_D(RAL_UE, "\n Numerical value: "); - - for (i = 0; i < 8; i++) { - for (j=0; j<4; j++) { - addr6p[i][j]= toupper(addr6p[i][j]); - - if ((addr6p[i][j] >= 'A') && (addr6p[i][j] <= 'F')) { - temp_addr[(4*i)+j] =(unsigned short int)(addr6p[i][j]-'A')+10; - } else if ((addr6p[i][j] >= '0') && (addr6p[i][j] <= '9')) { - temp_addr[(4*i)+j] =(unsigned short int)(addr6p[i][j]-'0'); - } - } - - my_addr[2*i]= (16*temp_addr[(4*i)])+temp_addr[(4*i)+1]; - my_addr[(2*i)+1]= (16*temp_addr[(4*i)+2])+temp_addr[(4*i)+3]; - - } - - for (i=0; i<16; i++) { - LOG_D(RAL_UE, "-%hhx-",my_addr[i]); - } - - LOG_D(RAL_UE, "\n\n"); - } - } - } - - fclose(f); - - if (!intf_found) { - LOG_E(RAL_UE, "interface not found\n\n"); - } - } - } - - - //--------------------------------------------------------------------------- - void mRAL_init_default_values(void) - //--------------------------------------------------------------------------- - { - g_conf_ue_ral_listening_port = UE_DEFAULT_LOCAL_PORT_RAL; - g_conf_ue_ral_ip_address = UE_DEFAULT_IP_ADDRESS_RAL; - g_conf_ue_ral_link_id = UE_DEFAULT_LINK_ID_RAL; - g_conf_ue_ral_link_address = UE_DEFAULT_LINK_ADDRESS_RAL; - g_conf_ue_mihf_remote_port = UE_DEFAULT_REMOTE_PORT_MIHF; - g_conf_ue_mihf_ip_address = UE_DEFAULT_IP_ADDRESS_MIHF; - g_conf_ue_mihf_id = UE_DEFAULT_MIHF_ID; - } - - //--------------------------------------------------------------------------- - int mRAL_initialize(void) { - //--------------------------------------------------------------------------- - ral_ue_instance_t instance = 0; - module_id_t mod_id = 0; - char *char_tmp = NULL; - - MIH_C_init(); - - srand(time(NULL)); - - memset(g_ue_ral_obj, 0, sizeof(lte_ral_ue_object_t)*MAX_MODULES); - - g_ue_ral_fd2instance = hashtable_create (32, NULL, hash_free_int_func); - - for (mod_id = oai_emulation.info.first_ue_local; mod_id < oai_emulation.info.first_ue_local+ oai_emulation.info.nb_ue_local; mod_id++) { - - instance = mod_id + NB_eNB_INST; - char_tmp = calloc(1, strlen(g_conf_ue_ral_listening_port) + 3); // 2 digits + \0 ->99 mod_ids - sprintf(char_tmp,"%d", atoi(g_conf_ue_ral_listening_port) + mod_id); - g_ue_ral_obj[mod_id].ral_listening_port = char_tmp; - - g_ue_ral_obj[mod_id].ral_ip_address = strdup(g_conf_ue_ral_ip_address); - g_ue_ral_obj[mod_id].ral_link_address = strdup(g_conf_ue_ral_link_address); - - char_tmp = calloc(1, strlen(g_conf_ue_mihf_remote_port) + 3); // 2 digits + \0 ->99 mod_ids - sprintf(char_tmp, "%d", atoi(g_conf_ue_mihf_remote_port) + mod_id); - g_ue_ral_obj[mod_id].mihf_remote_port = char_tmp; - - g_ue_ral_obj[mod_id].mihf_ip_address = strdup(g_conf_ue_mihf_ip_address); - - char_tmp = calloc(1, strlen(g_conf_ue_mihf_id) + 3); // 2 digits + \0 ->99 mod_ids - sprintf(char_tmp, "%s%02d",g_conf_ue_mihf_id, mod_id); - g_ue_ral_obj[mod_id].mihf_id = char_tmp; - - char_tmp = calloc(1, strlen(g_conf_ue_ral_link_id) + 3); // 2 digits + \0 ->99 mod_ids - sprintf(char_tmp, "%s%02d",g_conf_ue_ral_link_id, mod_id); - g_ue_ral_obj[mod_id].link_id = char_tmp; - - char_tmp = NULL; - - printf("g_ue_ral_obj[%d].link_id=%s\n", mod_id, g_ue_ral_obj[mod_id].link_id); - // excluded MIH_C_LINK_AC_TYPE_NONE - // excluded MIH_C_LINK_AC_TYPE_LINK_LOW_POWER - g_ue_ral_obj[mod_id].mih_supported_action_list = MIH_C_LINK_AC_TYPE_LINK_DISCONNECT | - MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN | - MIH_C_LINK_AC_TYPE_LINK_POWER_UP | - MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR | - MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES | - MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES; - - - - g_ue_ral_obj[mod_id].mih_supported_link_event_list = MIH_C_BIT_LINK_DETECTED | - MIH_C_BIT_LINK_UP | - MIH_C_BIT_LINK_DOWN | - MIH_C_BIT_LINK_PARAMETERS_REPORT | - MIH_C_BIT_LINK_GOING_DOWN | - MIH_C_BIT_LINK_HANDOVER_IMMINENT | - MIH_C_BIT_LINK_HANDOVER_COMPLETE | - MIH_C_BIT_LINK_PDU_TRANSMIT_STATUS; - - g_ue_ral_obj[mod_id].mih_supported_link_command_list = MIH_C_BIT_LINK_EVENT_SUBSCRIBE | MIH_C_BIT_LINK_EVENT_UNSUBSCRIBE | - MIH_C_BIT_LINK_GET_PARAMETERS | MIH_C_BIT_LINK_CONFIGURE_THRESHOLDS | - MIH_C_BIT_LINK_ACTION; - - g_ue_ral_obj[mod_id].link_to_be_detected = MIH_C_BOOLEAN_TRUE; - - - - - g_ue_ral_obj[mod_id].link_mihcap_flag = MIH_C_BIT_EVENT_SERVICE_SUPPORTED | MIH_C_BIT_COMMAND_SERVICE_SUPPORTED | MIH_C_BIT_INFORMATION_SERVICE_SUPPORTED; - - g_ue_ral_obj[mod_id].net_caps = MIH_C_BIT_NET_CAPS_QOS_CLASS5 | MIH_C_BIT_NET_CAPS_INTERNET_ACCESS | MIH_C_BIT_NET_CAPS_MIH_CAPABILITY; - - - g_ue_ral_obj[mod_id].transaction_id = (MIH_C_TRANSACTION_ID_T)rand(); - - LOG_D(RAL_UE, " Connect to the MIH-F for module id instance %d...\n", mod_id, instance); - g_ue_ral_obj[mod_id].mih_sock_desc = -1; - AssertFatal (mRAL_mihf_connect(instance) >= 0, "%s : Could not connect to MIH-F...\n", __FUNCTION__); - itti_subscribe_event_fd(TASK_RAL_UE, g_ue_ral_obj[mod_id].mih_sock_desc); - hashtable_insert(g_ue_ral_fd2instance, g_ue_ral_obj[mod_id].mih_sock_desc, (void*)instance); - - mRAL_send_link_register_indication(instance, &g_ue_ral_obj[mod_id].transaction_id); - g_ue_ral_obj[mod_id].transaction_id += 1; - } - - return 0; - } - - void mRAL_process_file_descriptors(struct epoll_event *events, int nb_events) { - int i; - ral_ue_instance_t instance; - hashtable_rc_t rc; - - if (events == NULL) { - return; - } - - for (i = 0; i < nb_events; i++) { - rc = hashtable_get(g_ue_ral_fd2instance, events[i].data.fd, (void**)&instance); - - if (rc == HASH_TABLE_OK) { - mRAL_mih_link_process_message(instance); - } - } - } - - void* mRAL_task(void *args_p) { - int nb_events; - struct epoll_event *events; - MessageDef *msg_p = NULL; - const char *msg_name = NULL; - instance_t instance = 0; - - - mRAL_initialize(); - - itti_mark_task_ready (TASK_RAL_UE); - - // Set UE activation state - for (instance = NB_eNB_INST; instance < (NB_eNB_INST + NB_UE_INST); instance++) { - MessageDef *message_p; - - message_p = itti_alloc_new_message(TASK_RAL_UE, DEACTIVATE_MESSAGE); - itti_send_msg_to_task(TASK_L2L1, instance, message_p); - } - - while(1) { - // Wait for a message - itti_receive_msg (TASK_RAL_UE, &msg_p); - - if (msg_p != NULL) { - - msg_name = ITTI_MSG_NAME (msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); - - switch (ITTI_MSG_ID(msg_p)) { - case TERMINATE_MESSAGE: - // TO DO - itti_exit_task (); - break; - - case TIMER_HAS_EXPIRED: - LOG_D(RAL_UE, "Received %s\n", msg_name); - break; - - case RRC_RAL_SCAN_CONF: - LOG_D(RAL_UE, "Received %s\n", msg_name); - mRAL_rx_rrc_ral_scan_confirm(instance, msg_p); - break; - - case RRC_RAL_SYSTEM_INFORMATION_IND: - LOG_D(RAL_UE, "Received %s\n", msg_name); - mRAL_rx_rrc_ral_system_information_indication(instance, msg_p); - break; - - case RRC_RAL_CONNECTION_ESTABLISHMENT_IND: - LOG_D(RAL_UE, "Received %s\n", msg_name); - mRAL_rx_rrc_ral_connection_establishment_indication(instance, msg_p); - break; - - case RRC_RAL_CONNECTION_REESTABLISHMENT_IND: - LOG_D(RAL_UE, "Received %s\n", msg_name); - mRAL_rx_rrc_ral_connection_reestablishment_indication(instance, msg_p); - break; - - case RRC_RAL_CONNECTION_RECONFIGURATION_IND: - LOG_D(RAL_UE, "Received %s\n", msg_name); - mRAL_rx_rrc_ral_connection_reconfiguration_indication(instance, msg_p); - break; - - case RRC_RAL_CONNECTION_RECONFIGURATION_HO_IND: - LOG_D(RAL_UE, "Received %s\n", msg_name); - //mRAL_rx_rrc_ral_connection_reconfiguration_ho_indication(instance, msg_p); - break; - - case RRC_RAL_MEASUREMENT_REPORT_IND: - LOG_D(RAL_UE, "Received %s\n", msg_name); - mRAL_rx_rrc_ral_measurement_report_indication(instance, msg_p); - break; - - case RRC_RAL_CONNECTION_RELEASE_IND: - LOG_D(RAL_UE, "Received %s\n", msg_name); - mRAL_rx_rrc_ral_connection_release_indication(instance, msg_p); - break; - - case RRC_RAL_CONFIGURE_THRESHOLD_CONF: - LOG_D(RAL_UE, "Received %s\n", msg_name); - mRAL_rx_rrc_ral_configure_threshold_conf(instance, msg_p); - break; - - default: - LOG_E(RAL_UE, "Received unexpected message %s\n", msg_name); - break; - } - - itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - msg_p = NULL; - } - - nb_events = itti_get_events(TASK_RAL_UE, &events); - - /* Now handle notifications for other sockets */ - if (nb_events > 0) { - mRAL_process_file_descriptors(events, nb_events); - } - } - } diff --git a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_mih_execute.c b/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_mih_execute.c deleted file mode 100755 index fe7365d98b..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_mih_execute.c +++ /dev/null @@ -1,224 +0,0 @@ -/*************************************************************************** - lteRALue_mih_execute.c - description - *************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 1999 - 2013 Eurecom - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information - Openair Admin: openair_admin@eurecom.fr - Openair Tech : openair_tech@eurecom.fr - Forums : http://forums.eurecom.fsr/openairinterface - Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France -*******************************************************************************/ -/*! \file lteRALue_mih_execute.c - * \brief Execution of MIH primitives in LTE-RAL-UE - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#define LTE_RAL_UE -#define LTERALUE_MIH_MSG_C - -#include <assert.h> -//----------------------------------------------------------------------------- -#include "lteRALue.h" - - - - - -//----------------------------------------------------------------------------- -void mRAL_configure_thresholds_request(MIH_C_Message_Link_Configure_Thresholds_request_t* messageP) -{ - //----------------------------------------------------------------------------- - MIH_C_STATUS_T status; - MIH_C_LINK_CFG_STATUS_LIST_T link_cfg_status_list; - unsigned int threshold_index; - unsigned int link_index; - unsigned int result_index; - - // SAVE REQUEST - // IT IS ASSUMED SINCE IT IS NOT CLEAR IN SPECs THAT THERE IS NO NEED TO MERGE CONFIGURE_THRESHOLDS_requests - //memset(&ralpriv->mih_link_cfg_param_thresholds_list, 0, sizeof(MIH_C_LINK_CFG_PARAM_LIST_T)); - memcpy(&ralpriv->mih_link_cfg_param_thresholds_list, &messageP->primitive.LinkConfigureParameterList_list, sizeof(MIH_C_LINK_CFG_PARAM_LIST_T)); - - status = MIH_C_STATUS_SUCCESS; - - result_index = 0; - - for (link_index = 0; - link_index < messageP->primitive.LinkConfigureParameterList_list.length; - link_index++) { - - ralpriv->active_mih_link_cfg_param_threshold[link_index] = MIH_C_BOOLEAN_TRUE; - - for (threshold_index = 0; - threshold_index < messageP->primitive.LinkConfigureParameterList_list.val[link_index].threshold_list.length; - threshold_index ++) { - - memcpy(&link_cfg_status_list.val[result_index].link_param_type, - &messageP->primitive.LinkConfigureParameterList_list.val[link_index].link_param_type, - sizeof(MIH_C_LINK_PARAM_TYPE_T)); - - memcpy(&link_cfg_status_list.val[result_index].threshold, - &messageP->primitive.LinkConfigureParameterList_list.val[link_index].threshold_list.val[threshold_index], - sizeof(MIH_C_THRESHOLD_T)); - - // NOW, ALWAYS SAY OK FOR PARAMETERS, BUT MAY BE WE WILL PUT MIH_C_BOOLEAN_FALSE in active_mih_link_cfg_param_threshold[link_index] - link_cfg_status_list.val[result_index].config_status = MIH_C_CONFIG_STATUS_SUCCESS; - - result_index += 1; - } - } - - // Say following thresholds entries are not configured - for (link_index = messageP->primitive.LinkConfigureParameterList_list.length; - link_index < MIH_C_LINK_CFG_PARAM_LIST_LENGTH; - link_index++) { - ralpriv->active_mih_link_cfg_param_threshold[link_index] = MIH_C_BOOLEAN_FALSE; - } - - link_cfg_status_list.length = result_index; - - mRALte_send_configure_thresholds_confirm(&messageP->header.transaction_id,&status, &link_cfg_status_list); -} -/* -//----------------------------------------------------------------------------- -void mRAL_check_thresholds_signal_strength(MIH_C_THRESHOLD_VAL_T new_valP, MIH_C_THRESHOLD_VAL_T old_valP) { -//----------------------------------------------------------------------------- - - unsigned int threshold_index, threshold_index_mov; - unsigned int link_index; - unsigned int buffer_index; - MIH_C_THRESHOLD_VAL_T threshold_val; - MIH_C_THRESHOLD_XDIR_T threshold_xdir; - MIH_C_TH_ACTION_T th_action; - LIST(MIH_C_LINK_PARAM_RPT, LinkParametersReportList); - MIH_C_TRANSACTION_ID_T transaction_id; - MIH_C_LINK_TUPLE_ID_T link_identifier; - char buf[256]; - - DEBUG("%s new_val %d old_val %d\n", __FUNCTION__, new_valP, old_valP); - - LinkParametersReportList_list.length = 0; - for (link_index = 0; - link_index < MIH_C_LINK_CFG_PARAM_LIST_LENGTH; - link_index++) { - - if (ralpriv->active_mih_link_cfg_param_threshold[link_index] == MIH_C_BOOLEAN_TRUE) { - - if ( ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].link_param_type.choice == MIH_C_LINK_PARAM_TYPE_CHOICE_GEN) { - - th_action = ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].th_action; - - for (threshold_index = 0; - threshold_index < ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.length; - threshold_index ++) { - - threshold_val = ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index].threshold_val; - threshold_xdir = ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index].threshold_xdir; - - switch (th_action) { - case MIH_C_SET_NORMAL_THRESHOLD: - if (((threshold_xdir == MIH_C_ABOVE_THRESHOLD) && (old_valP <= threshold_val) && (new_valP > threshold_val)) || - ((threshold_xdir == MIH_C_BELOW_THRESHOLD) && (old_valP >= threshold_val) && (new_valP < threshold_val))) { - - memset(buf, 0, 256); - buffer_index = sprintf(buf, "CROSSED NORMAL THRESHOLD VAL %d DIR ", threshold_val); - buffer_index = MIH_C_THRESHOLD_XDIR2String2(&threshold_xdir, &buf[buffer_index]); - buffer_index = sprintf(buf, " with VAL %d\n", new_valP); - NOTICE("%s", buf); - - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type.choice = MIH_C_LINK_PARAM_TYPE_CHOICE_GEN; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type._union.link_param_gen = MIH_C_LINK_PARAM_GEN_SIGNAL_STRENGTH; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param._union.link_param_val = new_valP; - - LinkParametersReportList_list.val[LinkParametersReportList_list.length].choice = MIH_C_LINK_PARAM_RPT_CHOICE_THRESHOLD; - LinkParametersReportList_list.val[LinkParametersReportList_list.length]._union.threshold.threshold_val = threshold_val; - LinkParametersReportList_list.val[LinkParametersReportList_list.length]._union.threshold.threshold_xdir = threshold_xdir; - LinkParametersReportList_list.length = LinkParametersReportList_list.length + 1; - } - break; - case MIH_C_SET_ONE_SHOT_THRESHOLD: - if (((threshold_xdir == MIH_C_ABOVE_THRESHOLD) && (old_valP <= threshold_val) && (new_valP > threshold_val)) || - ((threshold_xdir == MIH_C_BELOW_THRESHOLD) && (old_valP >= threshold_val) && (new_valP < threshold_val))) { - - memset(buf, 0, 256); - buffer_index = sprintf(buf, "CROSSED ONE SHOT THRESHOLD VAL %d DIR ", threshold_val); - buffer_index = MIH_C_THRESHOLD_XDIR2String2(&threshold_xdir, &buf[buffer_index]); - buffer_index = sprintf(buf, " with VAL %d\n", new_valP); - NOTICE("%s", buf); - - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type.choice = MIH_C_LINK_PARAM_TYPE_CHOICE_GEN; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type._union.link_param_gen = MIH_C_LINK_PARAM_GEN_SIGNAL_STRENGTH; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param._union.link_param_val = new_valP; - - LinkParametersReportList_list.val[LinkParametersReportList_list.length].choice = MIH_C_LINK_PARAM_RPT_CHOICE_THRESHOLD; - LinkParametersReportList_list.val[LinkParametersReportList_list.length]._union.threshold.threshold_val = threshold_val; - LinkParametersReportList_list.val[LinkParametersReportList_list.length]._union.threshold.threshold_xdir = threshold_xdir; - LinkParametersReportList_list.length = LinkParametersReportList_list.length + 1; - - // Remove this threshold: shift Thresholds - for (threshold_index_mov = threshold_index; - threshold_index_mov < ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.length - 1; - threshold_index_mov ++) { - memcpy(&ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index_mov], - &ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index_mov+1], - sizeof(MIH_C_THRESHOLD_T)); - } - } - break; - // may be not necessary here - case MIH_C_CANCEL_THRESHOLD: - // shift Thresholds - for (threshold_index_mov = threshold_index; - threshold_index_mov < ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.length - 1; - threshold_index_mov ++) { - memcpy(&ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index_mov], - &ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index_mov+1], - sizeof(MIH_C_THRESHOLD_T)); - } - ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.length -= 1; - break; - default: - ERR("%s UNKNOWN TH ACTION FOUND, RETURN", __FUNCTION__); - return; - } - } - } - } - } - if (LinkParametersReportList_list.length > 0) { - transaction_id = MIH_C_get_new_transaction_id(); - - link_identifier.link_id.link_type = MIH_C_WIRELESS_UMTS; - link_identifier.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_set(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)&(ralpriv->ipv6_l2id[0]), strlen(DEFAULT_ADDRESS_3GPP)); - link_identifier.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - - mRAL_send_link_parameters_report_indication(&transaction_id, &link_identifier, &LinkParametersReportList_list); - } -} -*/ - - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_mih_msg.c b/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_mih_msg.c deleted file mode 100755 index 6a521d2bc3..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_mih_msg.c +++ /dev/null @@ -1,966 +0,0 @@ -/*************************************************************************** - lteRALue_mih_msg.c - description - *************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 1999 - 2013 Eurecom - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information - Openair Admin: openair_admin@eurecom.fr - Openair Tech : openair_tech@eurecom.fr - Forums : http://forums.eurecom.fsr/openairinterface - Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France -*******************************************************************************/ -/*! \file lteRALue_mih_msg.c - * \brief Interface for MIH primitives in LTE-RAL-UE - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#define LTE_RAL_UE -#define LTERALUE_MIH_MSG_C -//----------------------------------------------------------------------------- -#include "lteRALue.h" -#include "LAYER2/MAC/extern.h" -//----------------------------------------------------------------------------- -#define MSG_CODEC_RECV_BUFFER_SIZE 16400 -#define MSG_CODEC_SEND_BUFFER_SIZE 16400 - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -static u_int8_t g_msg_codec_recv_buffer[MSG_CODEC_RECV_BUFFER_SIZE] = {}; -static u_int8_t g_msg_codec_send_buffer[MSG_CODEC_SEND_BUFFER_SIZE] = {}; - -static char g_msg_print_buffer[8192] = {}; -static char g_msg_codec_print_buffer[8192] = {}; - - -//----------------------------------------------------------------------------- -int mRAL_send_to_mih(ral_ue_instance_t instanceP, u_int8_t *buffer_pP, size_t lenP) -{ - //----------------------------------------------------------------------------- - int result; - module_id_t mod_id = instanceP - NB_eNB_INST; - result = send(g_ue_ral_obj[mod_id].mih_sock_desc, (const void *)buffer_pP, lenP, 0); - - if (result != lenP) { - LOG_E(RAL_UE, "send_to_mih %d bytes failed, returned %d: %s\n", lenP, result, strerror(errno)); - } - - return result; -} - -//--------------------------------------------------------------------------- -int mRAL_mihf_connect(ral_ue_instance_t instanceP) -{ - //--------------------------------------------------------------------------- - struct addrinfo info; /* endpoint information */ - struct addrinfo *addr, *rp; /* endpoint address */ - int rc; /* returned error code */ - int optval; /* socket option value */ - module_id_t mod_id = instanceP - NB_eNB_INST; - - unsigned char buf[sizeof(struct sockaddr_in6)]; - - /* - * Initialize the remote MIH-F endpoint address information - */ - memset(&info, 0, sizeof(struct addrinfo)); - info.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ - info.ai_socktype = SOCK_DGRAM; /* Datagram socket */ - info.ai_flags = 0; - info.ai_protocol = 0; /* Any protocol */ - - rc = getaddrinfo(g_ue_ral_obj[mod_id].mihf_ip_address, g_ue_ral_obj[mod_id].mihf_remote_port, &info, &addr); - - if (rc != 0) { - LOG_E(RAL_UE, " getaddrinfo: %s\n", gai_strerror(rc)); - return -1; - } - - /* - * getaddrinfo() returns a linked list of address structures. - * Try each address until we successfully connect(2). If socket(2) - * (or connect(2)) fails, we (close the socket and) try the next address. - */ - for (rp = addr; rp != NULL; rp = rp->ai_next) { - - g_ue_ral_obj[mod_id].mih_sock_desc = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - - if (g_ue_ral_obj[mod_id].mih_sock_desc < 0) { - continue; - } - - optval = 1; - setsockopt(g_ue_ral_obj[mod_id].mih_sock_desc, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); - - /* - * Convert the RAL local network address - */ - if (rp->ai_family == AF_INET) { - /* IPv4 network address family */ - struct sockaddr_in *addr4 = NULL; - - LOG_D(RAL_UE, " %s is an ipv4 address\n", g_ue_ral_obj[mod_id].mihf_ip_address); - addr4 = (struct sockaddr_in *)(&buf[0]); - addr4->sin_port = htons(atoi(g_ue_ral_obj[mod_id].ral_listening_port)); - addr4->sin_family = AF_INET; - rc = inet_pton(AF_INET, g_ue_ral_obj[mod_id].ral_ip_address, &addr4->sin_addr); - } else if (rp->ai_family == AF_INET6) { - /* IPv6 network address family */ - struct sockaddr_in6 *addr6 = NULL; - - LOG_D(RAL_UE, " %s is an ipv6 address\n", g_ue_ral_obj[mod_id].mihf_ip_address); - addr6 = (struct sockaddr_in6 *)(&buf[0]); - addr6->sin6_port = htons(atoi(g_ue_ral_obj[mod_id].ral_listening_port)); - addr6->sin6_family = AF_INET6; - rc = inet_pton(AF_INET, g_ue_ral_obj[mod_id].ral_ip_address, &addr6->sin6_addr); - } else { - LOG_E(RAL_UE, " %s is an unknown address format %d\n", - g_ue_ral_obj[mod_id].mihf_ip_address, rp->ai_family); - return -1; - } - - if (rc < 0) { - /* The network address convertion failed */ - LOG_E(RAL_UE, " inet_pton(RAL IP address %s): %s\n", - g_ue_ral_obj[mod_id].ral_ip_address, strerror(rc)); - return -1; - } else if (rc == 0) { - /* The network address is not valid */ - LOG_E(RAL_UE, " RAL IP address %s is not valid\n", g_ue_ral_obj[mod_id].ral_ip_address); - return -1; - } - - /* Bind the socket to the local RAL network address */ - rc = bind(g_ue_ral_obj[mod_id].mih_sock_desc, (const struct sockaddr *)buf, - sizeof(struct sockaddr_in)); - - if (rc < 0) { - LOG_E(RAL_UE, " bind(RAL IP address %s): %s\n", - g_ue_ral_obj[mod_id].ral_ip_address, strerror(errno)); - return -1; - } - - /* Connect the socket to the remote MIH-F network address */ - if (connect(g_ue_ral_obj[mod_id].mih_sock_desc, rp->ai_addr, rp->ai_addrlen) == 0) { - LOG_N(RAL_UE, " RAL [%s:%s] is now UDP-CONNECTED to MIH-F [%s:%s]\n", - g_ue_ral_obj[mod_id].ral_ip_address, g_ue_ral_obj[mod_id].ral_listening_port, - g_ue_ral_obj[mod_id].mihf_ip_address, g_ue_ral_obj[mod_id].mihf_remote_port); - break; - } - - /* - * We failed to connect: - * Close the socket file descriptor and try to connect to an other - * address. - */ - close(g_ue_ral_obj[mod_id].mih_sock_desc); - } - - /* - * Unable to connect to a network address - */ - if (rp == NULL) { - LOG_E(RAL_UE, " Could not connect to MIH-F\n"); - return -1; - } - - freeaddrinfo(addr); - - return 0; -} - - -//----------------------------------------------------------------------------- -void MIH_C_3GPP_ADDR_load_3gpp_str_address(ral_ue_instance_t instanceP, MIH_C_3GPP_ADDR_T* _3gpp_addr_pP, u_int8_t* str_pP) -//----------------------------------------------------------------------------- -{ - int i, l; - u_int8_t val_temp; - unsigned char address_3gpp[32]; - unsigned char buf[3]; - u_int8_t _3gpp_byte_address[8]; - module_id_t mod_id = instanceP - NB_eNB_INST; - - strcpy((char *)address_3gpp, (char *)str_pP); - - for(l=0; l<8; l++) { - i=l*2; - buf[0]= address_3gpp[i]; - buf[1]= address_3gpp[i+1]; - buf[2]= '\0'; - //sscanf((const char *)buf,"%02x", &val_temp); - sscanf((const char *)buf,"%hhx", &val_temp); - _3gpp_byte_address[l] = val_temp; - } - - _3gpp_byte_address[7] += mod_id; - MIH_C_3GPP_ADDR_set(_3gpp_addr_pP, _3gpp_byte_address, 8); -} - - -/*************************************************************************** - Transmission side - ***************************************************************************/ - -//----------------------------------------------------------------------------- -void mRAL_send_link_register_indication(ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Register_indication_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Register_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)6; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - - message.primitive.Link_Id.link_type = MIH_C_WIRELESS_LTE; //MIH_C_WIRELESS_UMTS; -#ifdef USE_3GPP_ADDR_AS_LINK_ADDR - message.primitive.Link_Id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_load_3gpp_str_address(mod_id, &message.primitive.Link_Id.link_addr._union._3gpp_addr, (u_int8_t*)UE_DEFAULT_3GPP_ADDRESS); -#else - message.primitive.Link_Id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_3G_CELL_ID; - memcpy(message.primitive.Link_Id.link_addr._union._3gpp_3g_cell_id.plmn_id.val, &g_ue_ral_obj[mod_id].plmn_id, 3); - message.primitive.Link_Id.link_addr._union._3gpp_3g_cell_id.cell_id = g_ue_ral_obj[mod_id].cell_id; -#endif - //MIH_C_3GPP_ADDR_set(&message.primitive.Link_Id.link_addr._union._3gpp_addr, (u_int8_t*)&(g_ue_ral_obj[instanceP].ipv6_l2id[0]), strlen(UE_DEFAULT_3GPP_ADDRESS)); - ////MIH_C_3GPP_ADDR_set(&message.primitive.Link_Id.link_addr._union._3gpp_addr, (u_int8_t*)UE_DEFAULT_3GPP_ADDRESS, strlen(UE_DEFAULT_3GPP_ADDRESS)); - ////MIH_C_3GPP_ADDR_load_3gpp_str_address(&message.primitive.Link_Id.link_addr._union._3gpp_addr, (u_int8_t*)UE_DEFAULT_3GPP_ADDRESS); - - - message_total_length = MIH_C_Link_Message_Encode_Link_Register_indication(bb_p, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - MIH_C_LINK_ID2String(&message.primitive.Link_Id, g_msc_gen_buf); -#endif - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - printf("ERROR RAL_UE, : Send Link_Register.indication\n"); - LOG_E(RAL_UE, ": Send Link_Register.indication\n"); - } else { - printf("OK RAL_UE, : Send Link_Register.indication\n"); - LOG_D(RAL_UE, ": Sent Link_Register.indication\n"); - } - - free_BitBuffer(bb_p); -} -//----------------------------------------------------------------------------- -void mRAL_send_link_detected_indication(ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP, - MIH_C_LINK_DET_INFO_T *link_detected_info_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Detected_indication_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Detected_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - - memcpy(&message.primitive.LinkDetectedInfo, link_detected_info_pP, sizeof(MIH_C_LINK_DET_INFO_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Detected_indication(bb_p, &message); - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - LOG_E(RAL_UE, ": Send Link_Detected.indication\n"); - } else { - LOG_D(RAL_UE, ": Sent Link_Detected.indication\n"); - } - - free_BitBuffer(bb_p); -} -//----------------------------------------------------------------------------- -void mRAL_send_link_up_indication(ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP, - MIH_C_LINK_TUPLE_ID_T *link_identifier_pP, - MIH_C_LINK_ADDR_T *old_access_router_pP, - MIH_C_LINK_ADDR_T *new_access_router_pP, - MIH_C_IP_RENEWAL_FLAG_T *ip_renewal_flag_pP, - MIH_C_IP_MOB_MGMT_T *mobility_management_support_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Up_indication_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Up_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)2; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, link_identifier_pP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - - message.primitive.OldAccessRouter = old_access_router_pP; - message.primitive.NewAccessRouter = new_access_router_pP; - message.primitive.IPRenewalFlag = ip_renewal_flag_pP; - message.primitive.MobilityManagementSupport = mobility_management_support_pP; - - message_total_length = MIH_C_Link_Message_Encode_Link_Up_indication(bb_p, &message); - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - LOG_E(RAL_UE, ": Send Link_Up.indication\n"); - } else { - LOG_D(RAL_UE, ": Sent Link_Up.indication\n"); - } - - free_BitBuffer(bb_p); -} -//----------------------------------------------------------------------------- -void mRAL_send_link_parameters_report_indication(ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP, - MIH_C_LINK_TUPLE_ID_T *link_identifier_pP, - MIH_C_LINK_PARAM_RPT_LIST_T *link_parameters_report_list_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Parameters_Report_indication_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Parameters_Report_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)5; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, link_identifier_pP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - memcpy(&message.primitive.LinkParametersReportList_list, link_parameters_report_list_pP, sizeof(MIH_C_LINK_PARAM_RPT_LIST_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Parameters_Report_indication(bb_p, &message); - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - LOG_E(RAL_UE, ": Send Link_Parameters_Report.indication\n"); - } else { - LOG_D(RAL_UE, ": Sent Link_Parameters_Report.indication\n"); - } - - free_BitBuffer(bb_p); -} - -//----------------------------------------------------------------------------- -void mRAL_send_link_going_down_indication(ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP, - MIH_C_LINK_TUPLE_ID_T *link_identifier_pP, - MIH_C_UNSIGNED_INT2_T *time_interval_pP, - MIH_C_LINK_GD_REASON_T *link_going_down_reason_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Going_Down_indication_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Going_Down_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)6; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, link_identifier_pP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - message.primitive.TimeInterval = *time_interval_pP; - memcpy(&message.primitive.LinkGoingDownReason, link_going_down_reason_pP, sizeof(MIH_C_LINK_GD_REASON_T)); - - - message_total_length = MIH_C_Link_Message_Encode_Link_Going_Down_indication(bb_p, &message); - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - LOG_E(RAL_UE, ": Send Link_Going_Down.indication\n"); - } else { - LOG_D(RAL_UE, ": Sent Link_Going_Down.indication\n"); - } - - free_BitBuffer(bb_p); -} - -//----------------------------------------------------------------------------- -void mRAL_send_link_down_indication(ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP, - MIH_C_LINK_TUPLE_ID_T *link_identifier_pP, - MIH_C_LINK_ADDR_T *old_access_router_pP, - MIH_C_LINK_DN_REASON_T *reason_code_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Down_indication_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Going_Down_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)3; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, link_identifier_pP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - message.primitive.OldAccessRouter = old_access_router_pP; - memcpy(&message.primitive.ReasonCode, reason_code_pP, sizeof(MIH_C_LINK_DN_REASON_T)); - - - message_total_length = MIH_C_Link_Message_Encode_Link_Down_indication(bb_p, &message); - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - LOG_E(RAL_UE, ": Send Link_Down.indication\n"); - } else { - LOG_D(RAL_UE, ": Sent Link_Down.indication\n"); - } - - free_BitBuffer(bb_p); -} - -//----------------------------------------------------------------------------- -void mRAL_send_link_action_confirm(ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP, - MIH_C_STATUS_T *status_pP, - MIH_C_LINK_SCAN_RSP_LIST_T *scan_response_set_pP, - MIH_C_LINK_AC_RESULT_T *link_action_result_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Action_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Action_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)3; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - - message.primitive.Status = *status_pP; - message.primitive.ScanResponseSet_list = scan_response_set_pP; - message.primitive.LinkActionResult = link_action_result_pP; - - - message_total_length = MIH_C_Link_Message_Encode_Link_Action_confirm(bb_p, &message); - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - LOG_E(RAL_UE, ": Send Link_Action.confirm\n"); - } else { - LOG_D(RAL_UE, ": Sent Link_Action.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -//----------------------------------------------------------------------------- -void mRAL_send_capability_discover_confirm(ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP, - MIH_C_STATUS_T *status_pP, - MIH_C_LINK_EVENT_LIST_T *supported_link_event_list_pP, - MIH_C_LINK_CMD_LIST_T *supported_link_command_list_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Capability_Discover_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Capability_Discover_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - message.primitive.Status = *status_pP; - message.primitive.SupportedLinkEventList = supported_link_event_list_pP; - message.primitive.SupportedLinkCommandList = supported_link_command_list_pP; - - message_total_length = MIH_C_Link_Message_Encode_Capability_Discover_confirm(bb_p, &message); - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - LOG_E(RAL_UE, ": Send Link_Capability_Discover.confirm\n"); - } else { - LOG_D(RAL_UE, ": Sent Link_Capability_Discover.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -//----------------------------------------------------------------------------- -void mRAL_send_event_subscribe_confirm(ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP, - MIH_C_STATUS_T *status_pP, - MIH_C_LINK_EVENT_LIST_T *response_link_event_list_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Event_Subscribe_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Event_Subscribe_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)4; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - message.primitive.Status = *status_pP; - message.primitive.ResponseLinkEventList = response_link_event_list_pP; - - message_total_length = MIH_C_Link_Message_Encode_Event_Subscribe_confirm(bb_p, &message); - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - LOG_E(RAL_UE, ": Send Link_Event_Subscribe.confirm\n"); - } else { - LOG_D(RAL_UE, ": Sent Link_Event_Subscribe.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -//----------------------------------------------------------------------------- -void mRAL_send_event_unsubscribe_confirm(ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP, - MIH_C_STATUS_T *status_pP, - MIH_C_LINK_EVENT_LIST_T *response_link_event_list_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Event_Unsubscribe_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Event_Unsubscribe_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)5; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - message.primitive.Status = *status_pP; - message.primitive.ResponseLinkEventList = response_link_event_list_pP; - - message_total_length = MIH_C_Link_Message_Encode_Event_Unsubscribe_confirm(bb_p, &message); - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - LOG_E(RAL_UE, ": Send Link_Event_Unsubscribe.confirm\n"); - } else { - LOG_D(RAL_UE, ": Sent Link_Event_Unsubscribe.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -//----------------------------------------------------------------------------- -void mRAL_send_configure_thresholds_confirm(ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP, - MIH_C_STATUS_T *status_pP, - MIH_C_LINK_CFG_STATUS_LIST_T *link_configure_status_list_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Configure_Thresholds_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Configure_Thresholds_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)2; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - message.primitive.Status = *status_pP; - message.primitive.LinkConfigureStatusList_list = link_configure_status_list_pP; - - message_total_length = MIH_C_Link_Message_Encode_Configure_Thresholds_confirm(bb_p, &message); - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - LOG_E(RAL_UE, ": Send Link_Configure_Threshold.confirm\n"); - } else { - LOG_D(RAL_UE, ": Sent Link_Configure_Threshold.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -//----------------------------------------------------------------------------- -void mRAL_send_get_parameters_confirm (ral_ue_instance_t instanceP, - MIH_C_TRANSACTION_ID_T *transaction_id_pP, - MIH_C_STATUS_T *status_pP, - MIH_C_LINK_PARAM_LIST_T *link_parameters_status_list_pP, - MIH_C_LINK_STATES_RSP_LIST_T *link_states_response_list_pP, - MIH_C_LINK_DESC_RSP_LIST_T *link_descriptors_response_list_pP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Get_Parameters_confirm_t message; - Bit_Buffer_t *bb_p; - int message_total_length; - module_id_t mod_id = instanceP - NB_eNB_INST; - - - bb_p = new_BitBuffer_0(); - BitBuffer_wrap(bb_p, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Get_Parameters_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *transaction_id_pP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_ue_ral_obj[mod_id].link_id, strlen(g_ue_ral_obj[mod_id].link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_ue_ral_obj[mod_id].mihf_id, strlen(g_ue_ral_obj[mod_id].mihf_id)); - - message.primitive.Status = *status_pP; - message.primitive.LinkParametersStatusList_list = link_parameters_status_list_pP; - message.primitive.LinkStatesResponse_list = link_states_response_list_pP; - message.primitive.LinkDescriptorsResponse_list = link_descriptors_response_list_pP; - - message_total_length = MIH_C_Link_Message_Encode_Get_Parameters_confirm(bb_p, &message); - - if (mRAL_send_to_mih(instanceP, bb_p->m_buffer,message_total_length)<0) { - LOG_E(RAL_UE, ": Send Link_Get_Parameters.confirm\n"); - } else { - LOG_D(RAL_UE, ": Sent Link_Get_Parameters.confirm\n"); - } - - free_BitBuffer(bb_p); -} - -/*************************************************************************** - Reception side - ***************************************************************************/ - -//----------------------------------------------------------------------------- -int mRAL_mih_link_msg_decode(ral_ue_instance_t instanceP, - Bit_Buffer_t *bbP, - MIH_C_Message_Wrapper_t *message_wrapperP) -{ - //----------------------------------------------------------------------------- - int status = MIH_MESSAGE_DECODE_FAILURE; - MIH_C_HEADER_T header; - MIH_C_STATUS_T mih_status; - module_id_t mod_id = instanceP - NB_eNB_INST; - - - if ((bbP != NULL) && (message_wrapperP != NULL)) { - status = MIH_C_Link_Header_Decode(bbP, &header); - - if (status == MIH_HEADER_DECODE_TOO_SHORT) { - return MIH_MESSAGE_DECODE_TOO_SHORT; - } else if (status == MIH_HEADER_DECODE_FAILURE) { - return MIH_MESSAGE_DECODE_FAILURE; - } else if (status == MIH_HEADER_DECODE_BAD_PARAMETER) { - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - message_wrapperP->message_id = MIH_C_MESSAGE_ID(header.service_identifier, header.operation_code, header.action_identifier); - - switch (message_wrapperP->message_id) { - case MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_REQUEST_ID: - LOG_D(RAL_UE, " %s Received MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_REQUEST TID %u\n", __FUNCTION__, header.transaction_id); - memcpy(&message_wrapperP->_union_message.link_capability_discover_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Capability_Discover_request(bbP, &message_wrapperP->_union_message.link_capability_discover_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - MIH_C_Link_Message_Link_Capability_Discover_request2String(&message_wrapperP->_union_message.link_capability_discover_request, g_msg_print_buffer); - LOG_D(RAL_UE, "%s", g_msg_print_buffer); - - mih_status = MIH_C_STATUS_SUCCESS; - LOG_D(RAL_UE, "**\n"); - LOG_D(RAL_UE, " %s Sending MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_CONFIRM\n\n", __FUNCTION__); - - mRAL_send_capability_discover_confirm(instanceP, - &message_wrapperP->_union_message.link_capability_discover_request.header.transaction_id, - &mih_status, - &g_ue_ral_obj[mod_id].mih_supported_link_event_list, - &g_ue_ral_obj[mod_id].mih_supported_link_command_list); - } else { - } - - break; - - case MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_REQUEST_ID: - LOG_D(RAL_UE, " %s Received MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_REQUEST TID %u\n", __FUNCTION__, header.transaction_id); - memcpy(&message_wrapperP->_union_message.link_event_subscribe_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Event_Subscribe_request(bbP, &message_wrapperP->_union_message.link_event_subscribe_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - LOG_D(RAL_UE, "**\n"); - - mRAL_subscribe_request(instanceP, &message_wrapperP->_union_message.link_event_subscribe_request); - } else { - } - - break; - - case MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_REQUEST_ID: - LOG_D(RAL_UE, " %s Received MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_REQUEST TID %u\n", __FUNCTION__, header.transaction_id); - memcpy(&message_wrapperP->_union_message.link_event_unsubscribe_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Event_Unsubscribe_request(bbP, &message_wrapperP->_union_message.link_event_unsubscribe_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - LOG_D(RAL_UE, "**\n"); - mRAL_unsubscribe_request(instanceP, &message_wrapperP->_union_message.link_event_unsubscribe_request); - } else { - } - - break; - - case MIH_C_MESSAGE_LINK_GET_PARAMETERS_REQUEST_ID: - LOG_D(RAL_UE, " %s Received MIH_C_MESSAGE_LINK_GET_PARAMETERS_REQUEST TID %u\n", __FUNCTION__, header.transaction_id); - memcpy(&message_wrapperP->_union_message.link_get_parameters_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Get_Parameters_request(bbP, &message_wrapperP->_union_message.link_get_parameters_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - LOG_D(RAL_UE, "**\n"); - mRAL_get_parameters_request(instanceP, &message_wrapperP->_union_message.link_get_parameters_request); - } else { - } - - break; - - case MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_REQUEST_ID: - LOG_D(RAL_UE, " %s Received MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_REQUEST TID %u\n", __FUNCTION__, header.transaction_id); - memcpy(&message_wrapperP->_union_message.link_configure_thresholds_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Configure_Thresholds_request(bbP, &message_wrapperP->_union_message.link_configure_thresholds_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - LOG_D(RAL_UE, "**\n"); - mRAL_configure_thresholds_request(instanceP, &message_wrapperP->_union_message.link_configure_thresholds_request); - } else { - } - - break; - - case MIH_C_MESSAGE_LINK_ACTION_REQUEST_ID: - LOG_D(RAL_UE, " %s Received MIH_C_MESSAGE_LINK_ACTION_REQUEST TID %u\n", __FUNCTION__, header.transaction_id); - memcpy(&message_wrapperP->_union_message.link_action_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Action_request(bbP, &message_wrapperP->_union_message.link_action_request); - - if (status == MIH_MESSAGE_DECODE_OK) { - LOG_D(RAL_UE, "**\n"); - mRAL_action_request(instanceP, &message_wrapperP->_union_message.link_action_request); - } else { - } - - break; - - default: - LOG_W(RAL_UE, "UNKNOWN MESSAGE ID SID %d, OP_CODE %d, AID %d\n", header.service_identifier, header.operation_code, header.action_identifier); - status = MIH_MESSAGE_DECODE_FAILURE; - - return status; - } - } else { - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - return status; -} - -//----------------------------------------------------------------------------- -int mRAL_mih_link_process_message(ral_ue_instance_t instanceP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Wrapper_t message_wrapper; - int nb_bytes_received ; - int nb_bytes_decoded ; - int total_bytes_to_decode ; - int status ; - Bit_Buffer_t *bb_p; - struct sockaddr_in udp_socket; - socklen_t sockaddr_len; - module_id_t mod_id = instanceP - NB_eNB_INST; - - total_bytes_to_decode = 0; - nb_bytes_received = 0; - - bb_p = new_BitBuffer_0(); - - nb_bytes_received = recvfrom(g_ue_ral_obj[mod_id].mih_sock_desc, - (void *)g_msg_codec_recv_buffer, - MSG_CODEC_RECV_BUFFER_SIZE, - 0, - (struct sockaddr *) &udp_socket, - &sockaddr_len); - - if (nb_bytes_received > 0) { - LOG_D(RAL_UE, " \n"); - LOG_D(RAL_UE, " %s: Received %d bytes from MIHF\n", __FUNCTION__, nb_bytes_received); - total_bytes_to_decode += nb_bytes_received; - BitBuffer_wrap(bb_p, g_msg_codec_recv_buffer, total_bytes_to_decode); - status = mRAL_mih_link_msg_decode(instanceP, bb_p, &message_wrapper); - nb_bytes_decoded = BitBuffer_getPosition(bb_p); - - if (status == MIH_MESSAGE_DECODE_OK) { - if (nb_bytes_decoded > 0) { - total_bytes_to_decode = total_bytes_to_decode - nb_bytes_decoded; - - // if remaining bytes to decode - if (total_bytes_to_decode > 0) { - //shift left bytes in buffer - memcpy(g_msg_codec_recv_buffer, &g_msg_codec_recv_buffer[nb_bytes_decoded], nb_bytes_decoded); - - //shift left again bytes in buffer - if (total_bytes_to_decode > nb_bytes_decoded) { - memcpy(&g_msg_codec_recv_buffer[nb_bytes_decoded], &g_msg_codec_recv_buffer[nb_bytes_decoded], total_bytes_to_decode - nb_bytes_decoded); - } - - // not necessary - memset(&g_msg_codec_recv_buffer[total_bytes_to_decode], 0 , MSG_CODEC_RECV_BUFFER_SIZE - total_bytes_to_decode); - - } - } - - // data could not be decoded - } else if (status == MIH_MESSAGE_DECODE_FAILURE) { - memset(g_msg_codec_recv_buffer, 0, MSG_CODEC_RECV_BUFFER_SIZE); - total_bytes_to_decode = 0; - } else if (status == MIH_MESSAGE_DECODE_TOO_SHORT) { - } - - LOG_D(RAL_UE, " \n"); - } - - free_BitBuffer(bb_p); - return 0; -} diff --git a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_parameters.c b/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_parameters.c deleted file mode 100755 index fd6e9a7f59..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_parameters.c +++ /dev/null @@ -1,145 +0,0 @@ -/*************************************************************************** - lteRALue_parameters.c - description - *************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 1999 - 2013 Eurecom - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information - Openair Admin: openair_admin@eurecom.fr - Openair Tech : openair_tech@eurecom.fr - Forums : http://forums.eurecom.fsr/openairinterface - Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France -*******************************************************************************/ -/*! \file lteRALue_mih_execute.c - * \brief Execution of MIH primitives in LTE-RAL-UE - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#define LTE_RAL_UE -#define LTERALUE_PARAMETERS_C -//----------------------------------------------------------------------------- -#include "lteRALue.h" - -//----------------------------------------------------------------------------- -void mRAL_get_parameters_request(ral_ue_instance_t instanceP, - MIH_C_Message_Link_Get_Parameters_request_t *messageP) -{ - //----------------------------------------------------------------------------- - MIH_C_STATUS_T status; - MIH_C_LINK_PARAM_LIST_T link_parameters_status_list; - MIH_C_LINK_STATES_RSP_LIST_T link_states_response_list; - MIH_C_LINK_DESC_RSP_LIST_T link_descriptors_response_list; - unsigned int link_index; - - // SAVE REQUEST - // MAY BE MERGE REQUESTS ? - //memcpy(&g_link_cfg_param_thresholds_list, &messageP->primitive.LinkConfigureParameterList_list, sizeof(MIH_C_LINK_CFG_PARAM_LIST_T)); - - status = MIH_C_STATUS_SUCCESS; - - for (link_index = 0; - link_index < messageP->primitive.LinkParametersRequest_list.length; - link_index++) { - - //------------------------------------------------ - // MIH_C_LINK_PARAM_LIST_T - //------------------------------------------------ - memcpy(&link_parameters_status_list.val[link_index].link_param_type, - &messageP->primitive.LinkParametersRequest_list.val[link_index], - sizeof(MIH_C_LINK_PARAM_TYPE_T)); - - switch (messageP->primitive.LinkParametersRequest_list.val[link_index].choice) { - case MIH_C_LINK_PARAM_TYPE_CHOICE_GEN: - link_parameters_status_list.val[link_index].choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - link_parameters_status_list.val[link_index]._union.link_param_val = MIH_C_LINK_PARAM_GEN_SIGNAL_STRENGTH; - break; - - case MIH_C_LINK_PARAM_TYPE_CHOICE_QOS: - link_parameters_status_list.val[link_index].choice = MIH_C_LINK_PARAM_CHOICE_QOS_PARAM_VAL; - link_parameters_status_list.val[link_index]._union.qos_param_val.choice = MIH_C_QOS_PARAM_VAL_CHOICE_AVG_PK_TX_DELAY; - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.length = 2; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[0].cos_id = 2; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[0].value = 20; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[1].cos_id = 3; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[2].value = 50; //?? - break; - - case MIH_C_LINK_PARAM_TYPE_CHOICE_LTE: - case MIH_C_LINK_PARAM_TYPE_CHOICE_GG: - case MIH_C_LINK_PARAM_TYPE_CHOICE_EDGE: - case MIH_C_LINK_PARAM_TYPE_CHOICE_ETH: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_11: - case MIH_C_LINK_PARAM_TYPE_CHOICE_C2K: - case MIH_C_LINK_PARAM_TYPE_CHOICE_FDD: - case MIH_C_LINK_PARAM_TYPE_CHOICE_HRPD: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_16: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_20: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_22: - default: - LOG_E(RAL_UE, "%s TO DO CONTINUE PROCESSING LinkParametersRequest_list of \n", __FUNCTION__); - } - - //------------------------------------------------ - // MIH_C_LINK_STATES_RSP_LIST_T - //------------------------------------------------ - if (messageP->primitive.LinkStatesRequest & MIH_C_BIT_LINK_STATES_REQ_OP_MODE) { - link_states_response_list.val[link_index].choice = 0; - link_states_response_list.val[link_index]._union.op_mode = MIH_C_OPMODE_NORMAL_MODE; - } else if (messageP->primitive.LinkStatesRequest & MIH_C_BIT_LINK_STATES_REQ_CHANNEL_ID) { - link_states_response_list.val[link_index].choice = 1; - link_states_response_list.val[link_index]._union.channel_id = PREDEFINED_CHANNEL_ID; - } else { - LOG_E(RAL_UE, "%s Invalid LinkStatesRequest in MIH_C_Link_Get_Parameters_request\n", __FUNCTION__); - // DEFAULT VALUES - link_states_response_list.val[link_index].choice = 0; - link_states_response_list.val[link_index]._union.op_mode = MIH_C_OPMODE_NORMAL_MODE; - } - - //------------------------------------------------ - // MIH_C_LINK_DESC_RSP_LIST_T - //------------------------------------------------ - if (messageP->primitive.LinkDescriptorsRequest & MIH_C_BIT_NUMBER_OF_CLASSES_OF_SERVICE_SUPPORTED) { - link_descriptors_response_list.val[link_index].choice = 0; - link_descriptors_response_list.val[link_index]._union.num_cos = PREDEFINED_CLASSES_SERVICE_SUPPORTED; - } else if (messageP->primitive.LinkDescriptorsRequest & MIH_C_BIT_NUMBER_OF_QUEUES_SUPPORTED) { - link_descriptors_response_list.val[link_index].choice = 1; - link_descriptors_response_list.val[link_index]._union.num_queue = PREDEFINED_QUEUES_SUPPORTED; - } else { - LOG_E(RAL_UE, "%s Invalid LinkDescriptorsRequest in MIH_C_Link_Get_Parameters_request\n", __FUNCTION__); - // DEFAULT VALUES - link_descriptors_response_list.val[link_index].choice = 0; - link_descriptors_response_list.val[link_index]._union.num_cos = PREDEFINED_CLASSES_SERVICE_SUPPORTED; - } - } - - link_parameters_status_list.length = messageP->primitive.LinkParametersRequest_list.length; - link_states_response_list.length = messageP->primitive.LinkParametersRequest_list.length; - link_descriptors_response_list.length = messageP->primitive.LinkParametersRequest_list.length; - - - mRAL_send_get_parameters_confirm(instanceP, - &messageP->header.transaction_id, - &status, - &link_parameters_status_list, - &link_states_response_list, - &link_descriptors_response_list); -} diff --git a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_process.c b/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_process.c deleted file mode 100755 index 1de7ba39f9..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_process.c +++ /dev/null @@ -1,301 +0,0 @@ -/*************************************************************************** - lteRALue_process.c - description - *************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 1999 - 2013 Eurecom - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information - Openair Admin: openair_admin@eurecom.fr - Openair Tech : openair_tech@eurecom.fr - Forums : http://forums.eurecom.fsr/openairinterface - Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France -*******************************************************************************/ -/*! \file lteRALue_process.c - * \brief Handling of measurements and connection in LTE-RAL-UE - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#define LTE_RAL_UE -#define LTERALUE_PROCESS_C -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <sys/socket.h> - -//----------------------------------------------------------------------------- -#include "lteRALue.h" -#include "PHY/extern.h" -/* -//--------------------------------------------------------------------------- -// Temp - Enter hard-coded measures in IAL -void IAL_NAS_measures_init(void){ -//--------------------------------------------------------------------------- -#ifdef DEBUG_MRALU_MEASURES - DEBUG("Entering IAL_NAS_measures_init \n\n"); -#endif -#ifdef RAL_DUMMY - ralpriv->num_measures = 3; -#endif -#ifdef RAL_REALTIME - ralpriv->num_measures = 1; -#endif - ralpriv->meas_cell_id[0] = 0; -#ifdef MIH_USER_CONTROL - ralpriv->last_meas_level[0] = 0; -#else - ralpriv->last_meas_level[0] = 30; -#endif - ralpriv->integrated_meas_level[0] = ralpriv->last_meas_level[0]; - ralpriv->provider_id[0] = 25; - ralpriv->meas_cell_id[1] = 1; - ralpriv->last_meas_level[1] = 50; - ralpriv->integrated_meas_level[1] = ralpriv->last_meas_level[1]; - ralpriv->provider_id[1] = 1; - ralpriv->meas_cell_id[2] = 20; - ralpriv->last_meas_level[2] = 20; - ralpriv->integrated_meas_level[2] = ralpriv->last_meas_level[2]; - ralpriv->provider_id[2] = 25; -} - -//--------------------------------------------------------------------------- -// Temp - Enter hard-coded measures in IAL -void IAL_NAS_measures_update(int i){ -//--------------------------------------------------------------------------- - DEBUG("\n"); -#ifdef DEBUG_MRALU_MEASURES - DEBUG("Entering IAL_NAS_measures_update\n"); -#endif - int j; - - //ralpriv->meas_cell_id[0] = ralpriv->cell_id; - j = i%2; - if (j==0){ - ralpriv->integrated_meas_level[2] = (ralpriv->integrated_meas_level[2] + (ralpriv->last_meas_level[2]/5)); - }else{ - ralpriv->integrated_meas_level[2] = (ralpriv->integrated_meas_level[2] - (ralpriv->last_meas_level[2]/5)); - } - ralpriv->curr_signal_level = ralpriv->integrated_meas_level[0]; - -// DEBUG ("Measure update - cell 1 %d, %d \n", ralpriv->last_meas_level[1], ralpriv->integrated_meas_level[1]); -} - -//--------------------------------------------------------------------------- -void IAL_integrate_measure(int measure, int i){ -//--------------------------------------------------------------------------- -#ifdef DEBUG_MRALU_MEASURES - DEBUG("Entering IAL_integrate_measure #%d\n", i); -#endif - int new_integrated = 0; - - new_integrated = (((10-LAMBDA)*ralpriv->last_meas_level[i])+(LAMBDA*measure))/10; - //apply correction to get a value between 0-100 - now is linear - new_integrated = (new_integrated*100)/MEAS_MAX_RSSI; - // print result - #ifdef DEBUG_MRALU_MEASURES - DEBUG (" Integrate measure: old %d, new %d, integrated %d\n", ralpriv->last_meas_level[i], measure,new_integrated ); - #endif - // store the result - ralpriv->last_meas_level[i] = measure; - ralpriv->prev_integrated_meas_level[i] = ralpriv->integrated_meas_level[i]; - ralpriv->integrated_meas_level[i] = new_integrated; - // if cell_id = 0, it means that there is no base station. Level should be 0 - // apply correction - if (!ralpriv->meas_cell_id[i]) - ralpriv->integrated_meas_level[i]=0; - -} - - -//--------------------------------------------------------------------------- -// poll for measures in NAS -void rallte_NAS_measures_polling(void){ -//--------------------------------------------------------------------------- - MIH_C_LINK_GD_REASON_T going_down_reason_code; - MIH_C_LINK_DN_REASON_T down_reason_code; - MIH_C_TRANSACTION_ID_T transaction_id; - MIH_C_LINK_TUPLE_ID_T link_identifier; - MIH_C_LINK_DET_INFO_T link_detected_info; - MIH_C_UNSIGNED_INT2_T time_interval; - //MIH_C_LINK_PARAM_RPT_LIST_T link_parameters_report_list; - - RAL_process_NAS_message(IO_OBJ_MEAS, IO_CMD_LIST, 0); - -// hard-coded trigger for test -#ifdef MRALU_SIMU_LINKDOWN - meas_counter ++; - if (meas_counter == 4){ - ralpriv->curr_signal_level = ralpriv->curr_signal_level/10; - IAL_integrate_measure(ralpriv->curr_signal_level, 0); - DEBUG ("\n signal level %d , integrated new value : %d\n",ralpriv->curr_signal_level, ralpriv->integrated_meas_level[0]); - } - - if (meas_counter == 5){ - ralpriv->curr_signal_level = 40; - IAL_integrate_measure(ralpriv->curr_signal_level, 0); - DEBUG ("\n signal level %d , integrated new value : %d\n",ralpriv->curr_signal_level, ralpriv->integrated_meas_level[0]); - } - if (meas_counter == 6){ - ralpriv->curr_signal_level = 0; - IAL_integrate_measure(ralpriv->curr_signal_level, 0); - DEBUG ("\n signal level %d , integrated new value : %d\n",ralpriv->curr_signal_level, ralpriv->integrated_meas_level[0]); - } -#endif - DEBUG ("signal level %d , integrated new value : %d , integrated old value : (%d)\n", - ralpriv->curr_signal_level, - ralpriv->integrated_meas_level[0], - ralpriv->prev_integrated_meas_level[0]); -// condition still TBD - message dropped or level = 0 - if ((!ralpriv->curr_signal_level) && - (ralpriv->link_to_be_detected == MIH_C_BOOLEAN_FALSE) && - (ralpriv->state != DISCONNECTED)) { - transaction_id = MIH_C_get_new_transaction_id(); - down_reason_code = MIH_C_LINK_DOWN_REASON_NO_RESOURCE; - link_identifier.link_id.link_type = MIH_C_WIRELESS_UMTS; - link_identifier.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - //MIH_C_3GPP_ADDR_load_3gpp_str_address(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP); - //MIH_C_3GPP_ADDR_set(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP, strlen(DEFAULT_ADDRESS_3GPP)); - MIH_C_3GPP_ADDR_set(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)&(ralpriv->ipv6_l2id[0]), strlen(DEFAULT_ADDRESS_3GPP)); - link_identifier.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - - mRAL_send_link_down_indication(&transaction_id, &link_identifier, NULL, &down_reason_code); - - ralpriv->link_to_be_detected = MIH_C_BOOLEAN_TRUE; - // warning may be repeated several times - } else - if ((ralpriv->link_to_be_detected == MIH_C_BOOLEAN_FALSE) && - (ralpriv->curr_signal_level <= ralpriv->integrated_meas_level[0]) && - (ralpriv->integrated_meas_level[0] < ralpriv->prev_integrated_meas_level[0]) && - (ralpriv->integrated_meas_level[0] < PREDEFINED_LINK_GOING_DOWN_INDICATION_SIG_STRENGTH) && - (ralpriv->state != DISCONNECTED)) { - - transaction_id = MIH_C_get_new_transaction_id(); - link_identifier.link_id.link_type = MIH_C_WIRELESS_UMTS; - link_identifier.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - //MIH_C_3GPP_ADDR_load_3gpp_str_address(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP); - //MIH_C_3GPP_ADDR_set(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP, strlen(DEFAULT_ADDRESS_3GPP)); - MIH_C_3GPP_ADDR_set(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)&(ralpriv->ipv6_l2id[0]), strlen(DEFAULT_ADDRESS_3GPP)); - link_identifier.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - time_interval = (MIH_C_UNSIGNED_INT2_T)0; // unknown - going_down_reason_code = MIH_C_LINK_GOING_DOWN_REASON_LINK_PARAMETER_DEGRADING; - // - mRAL_send_link_going_down_indication(&transaction_id, &link_identifier, &time_interval, &going_down_reason_code); - - } else - if ((ralpriv->link_to_be_detected == MIH_C_BOOLEAN_TRUE) && - ((ralpriv->mih_subscribe_req_event_list && (MIH_C_BIT_LINK_DETECTED + MIH_C_BIT_LINK_UP))>0)&& - (ralpriv->curr_signal_level > PREDEFINED_LINK_DETECTED_INDICATION_SIG_STRENGTH)) { - transaction_id = MIH_C_get_new_transaction_id(); - // MIH_C_LINK_TUPLE_ID_T - link_detected_info.link_tuple_id.link_id.link_type = MIH_C_WIRELESS_UMTS; - link_detected_info.link_tuple_id.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_set(&link_detected_info.link_tuple_id.link_id.link_addr._union._3gpp_addr, (u_int8_t*)&(ralpriv->ipv6_l2id[0]), strlen(DEFAULT_ADDRESS_3GPP)); - link_detected_info.link_tuple_id.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - // MIH_C_NETWORK_ID_T - MIH_C_NETWORK_ID_set(&link_detected_info.network_id, (u_int8_t *)PREDEFINED_MIH_NETWORK_ID, strlen(PREDEFINED_MIH_NETWORK_ID)); - // MIH_C_NET_AUX_ID_T - MIH_C_NET_AUX_ID_set(&link_detected_info.net_aux_id, (u_int8_t *)PREDEFINED_MIH_NETAUX_ID, strlen(PREDEFINED_MIH_NETAUX_ID)); - // MIH_C_SIG_STRENGTH_T - link_detected_info.sig_strength.choice = MIH_C_SIG_STRENGTH_CHOICE_PERCENTAGE; - link_detected_info.sig_strength._union.percentage = ralpriv->curr_signal_level; - // sinr - link_detected_info.sinr = PREDEFINED_LINK_DETECTED_INDICATION_SINR; - // MIH_C_LINK_DATA_RATE_T - link_detected_info.link_data_rate = PREDEFINED_LINK_DETECTED_INDICATION_LINK_DATA_RATE; - // MIH_C_LINK_MIHCAP_FLAG - link_detected_info.link_mihcap_flag = MIH_C_BIT_EVENT_SERVICE_SUPPORTED | - MIH_C_BIT_COMMAND_SERVICE_SUPPORTED | - MIH_C_BIT_INFORMATION_SERVICE_SUPPORTED; - // MIH_C_NET_CAPS_T - link_detected_info.net_caps = MIH_C_BIT_NET_CAPS_QOS_CLASS0 | - MIH_C_BIT_NET_CAPS_QOS_CLASS1 | - MIH_C_BIT_NET_CAPS_INTERNET_ACCESS; - // - mRAL_send_link_detected_indication(&transaction_id, &link_detected_info); - ralpriv->link_to_be_detected = MIH_C_BOOLEAN_FALSE; - } - // LG: TO DO CHECK IF INDEX IS 0 - mRAL_check_thresholds_signal_strength(ralpriv->integrated_meas_level[0], ralpriv->prev_integrated_meas_level[0]); -} - -//--------------------------------------------------------------------------- -// find correponding cell in NAS measures -int rallte_NAS_corresponding_cell(int req_index) -//--------------------------------------------------------------------------- -{ - int index, i=0; - - while ((i<=ralpriv->num_measures)&&(ralpriv->req_cell_id[req_index]!=ralpriv->meas_cell_id[i])) - i++; - - index = i; - return index; -} - -//--------------------------------------------------------------------------- -void rallte_verifyPendingConnection(void){ -//--------------------------------------------------------------------------- - int if_ready = 0; - MIH_C_LINK_TUPLE_ID_T link_identifier; - - if ((ralpriv->pending_req_flag)%5==0){ - DEBUG("**\n"); - DEBUG("Pending Req Flag %d\n", ralpriv->pending_req_flag); - DEBUG(" >>>> verifyPendingConnection "); - //poll status from driver -#ifdef RAL_DUMMY - IAL_process_DNAS_message(IO_OBJ_CNX, IO_CMD_LIST, ralpriv->cell_id); - - if ((ralpriv->nas_state == NAS_CONNECTED)&&(ralpriv->num_rb>=1)){ - if_ready = 1; - ralpriv->state = CONNECTED; - } -#endif -#ifdef RAL_REALTIME - RAL_process_NAS_message(IO_OBJ_CNX, IO_CMD_LIST, ralpriv->cell_id); - if ((ralpriv->nas_state == NAS_CX_DCH)&&(ralpriv->num_rb>=1)){ - if_ready = 1; - ralpriv->state = CONNECTED; - } -#endif - if ((if_ready==1)||(ralpriv->pending_req_flag > 100)){ - if (ralpriv->pending_req_flag > 100){ - ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_FAILURE; - } - mRAL_send_link_action_confirm(&ralpriv->pending_req_transaction_id, &ralpriv->pending_req_status, NULL, &ralpriv->pending_req_ac_result); - - - ////alternative : send linkup - //link_identifier.link_id.link_type = MIH_C_WIRELESS_UMTS; - //link_identifier.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - //MIH_C_3GPP_ADDR_set(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)&(ralpriv->ipv6_l2id[0]), strlen(DEFAULT_ADDRESS_3GPP)); - //link_identifier.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - //mRAL_send_link_up_indication(&ralpriv->pending_req_transaction_id, &link_identifier, NULL, NULL, NULL, NULL); - - - DEBUG("After response, Pending Req Flag = %d, cell_id = %d\n", ralpriv->pending_req_flag, ralpriv->cell_id); - ralpriv->pending_req_flag = 0; - // Link_up Ind not needed anymore - //sleep(2); - //mRALte_send_link_up_indication(); - } - } -}*/ diff --git a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_rrc_msg.c b/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_rrc_msg.c deleted file mode 100755 index c93e3b0b00..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_rrc_msg.c +++ /dev/null @@ -1,283 +0,0 @@ -/***************************************************************************** - * Eurecom OpenAirInterface 3 - * Copyright(c) 2012 Eurecom - * - * Source mRAL_subscribe.c - * - * Version 0.1 - * - * Date 11/27/2013 - * - * Product MIH RAL LTE - * - * Subsystem - * - * Authors Lionel Gauthier - * - * Description - * - *****************************************************************************/ -#define LTE_RAL_UE -#define LTE_RAL_UE_RRC_MSG_C -#include "lteRALue.h" -#include "LAYER2/MAC/extern.h" - -//--------------------------------------------------------------------------------------------------------------------- -static int ueid2eui48(uint8_t *euiP, uint8_t* ue_idP) -//--------------------------------------------------------------------------------------------------------------------- -{ - // inspired by linux-source-3.2.0/net/ipv6/addrconf.c - memcpy(euiP, ue_idP, 3); - memcpy(euiP + 5, ue_idP + 3, 3); - euiP[3] = 0xFF; - euiP[4] = 0xFE; - euiP[0] ^= 2; - return 0; -} - -//--------------------------------------------------------------------------------------------------------------------- -void mRAL_rx_rrc_ral_scan_confirm(instance_t instanceP, - MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - MIH_C_STATUS_T status; - MIH_C_LINK_SCAN_RSP_LIST_T scan_rsp_list; - MIH_C_LINK_AC_RESULT_T ac_result; - int i; - - status = MIH_C_STATUS_SUCCESS; - ac_result = MIH_C_LINK_AC_RESULT_SUCCESS; - memset(&scan_rsp_list, 0, sizeof(MIH_C_LINK_SCAN_RSP_LIST_T)); - - for (i = 0 ; i < RRC_RAL_SCAN_CONF (msg_pP).num_scan_resp; i++) { - // TO DO - memcpy(&scan_rsp_list.val[i].link_addr, &RRC_RAL_SCAN_CONF (msg_pP).link_scan_resp[i].link_addr, sizeof(MIH_C_LINK_ADDR_T)); - // TO DO - memcpy(&scan_rsp_list.val[i].network_id, &RRC_RAL_SCAN_CONF (msg_pP).link_scan_resp[i].network_id, sizeof(MIH_C_NETWORK_ID_T)); - - scan_rsp_list.val[i].sig_strength.choice = RRC_RAL_SCAN_CONF (msg_pP).link_scan_resp[i].sig_strength.choice; - - switch (scan_rsp_list.val[i].sig_strength.choice) { - case RAL_SIG_STRENGTH_CHOICE_DBM: - scan_rsp_list.val[i].sig_strength._union.dbm = RRC_RAL_SCAN_CONF (msg_pP).link_scan_resp[i].sig_strength._union.dbm; - break; - - case RAL_SIG_STRENGTH_CHOICE_PERCENTAGE: - scan_rsp_list.val[i].sig_strength._union.percentage = RRC_RAL_SCAN_CONF (msg_pP).link_scan_resp[i].sig_strength._union.percentage; - break; - - default: - LOG_E(RAL_UE, "INVALID RRC_RAL_SCAN_CONF field sig_strength.choice %d\n", scan_rsp_list.val[i].sig_strength.choice); - status = MIH_C_STATUS_UNSPECIFIED_FAILURE; - } - - scan_rsp_list.length += 1; - } - - mRAL_send_link_action_confirm(instanceP, - &RRC_RAL_SCAN_CONF (msg_pP).transaction_id, - &status, - &scan_rsp_list, - &ac_result); -} - - -//--------------------------------------------------------------------------------------------------------------------- -void mRAL_rx_rrc_ral_system_information_indication(instance_t instanceP, - MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - MIH_C_LINK_DET_INFO_T link_det_info; - int i; - module_id_t mod_id = instanceP - NB_eNB_INST; - - memset(&link_det_info, 0, sizeof(MIH_C_LINK_DET_INFO_T)); - - // save cell parameters - g_ue_ral_obj[mod_id].cell_id = RRC_RAL_SYSTEM_INFORMATION_IND(msg_pP).cell_id; - memcpy(&g_ue_ral_obj[mod_id].plmn_id, &RRC_RAL_SYSTEM_INFORMATION_IND(msg_pP).plmn_id, sizeof(g_ue_ral_obj[mod_id].plmn_id)); - - // link id - link_det_info.link_tuple_id.link_id.link_type = MIH_C_WIRELESS_LTE; -#ifdef USE_3GPP_ADDR_AS_LINK_ADDR - link_det_info.link_tuple_id.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_load_3gpp_str_address(mod_id, &link_det_info.link_tuple_id.link_id.link_addr._union._3gpp_addr, (u_int8_t*)UE_DEFAULT_3GPP_ADDRESS); -#else - link_det_info.link_tuple_id.link_id.link_addr.choice = MIH_C_CHOICE_3GPP_3G_CELL_ID; - - // preserve byte order of plmn id - memcpy(link_det_info.link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val, &RRC_RAL_SYSTEM_INFORMATION_IND(msg_pP).plmn_id, 3); - link_det_info.link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id = RRC_RAL_SYSTEM_INFORMATION_IND(msg_pP).cell_id; - - LOG_D(RAL_UE, "PLMN ID %d.%d.%d\n", link_det_info.link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[0], - link_det_info.link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[1], - link_det_info.link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[2]); - LOG_D(RAL_UE, "CELL ID %d\n", link_det_info.link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id); -#endif - //The optional LINK_ADDR may contains a link address of PoA. - link_det_info.link_tuple_id.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - - MIH_C_NETWORK_ID_set(&link_det_info.network_id, (u_int8_t *)PREDEFINED_MIH_NETWORK_ID, strlen(PREDEFINED_MIH_NETWORK_ID)); - - MIH_C_NET_AUX_ID_set(&link_det_info.net_aux_id, (u_int8_t *)PREDEFINED_MIH_NETAUX_ID, strlen(PREDEFINED_MIH_NETAUX_ID)); - - link_det_info.sig_strength.choice = MIH_C_SIG_STRENGTH_CHOICE_DBM; - link_det_info.sig_strength._union.dbm = RRC_RAL_SYSTEM_INFORMATION_IND(msg_pP).dbm; - - link_det_info.sinr = RRC_RAL_SYSTEM_INFORMATION_IND(msg_pP).sinr; - - link_det_info.link_data_rate = RRC_RAL_SYSTEM_INFORMATION_IND(msg_pP).link_data_rate; - - link_det_info.link_mihcap_flag = g_ue_ral_obj[mod_id].link_mihcap_flag; - - link_det_info.net_caps = g_ue_ral_obj[mod_id].net_caps; - - mRAL_send_link_detected_indication(instanceP, &g_ue_ral_obj[mod_id].transaction_id, &link_det_info); - - g_ue_ral_obj[mod_id].transaction_id ++; - -} -//--------------------------------------------------------------------------------------------------------------------- -void mRAL_rx_rrc_ral_connection_establishment_indication(instance_t instanceP, - MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - MIH_C_LINK_TUPLE_ID_T link_tuple_id; - module_id_t mod_id = instanceP - NB_eNB_INST; - - memset(&link_tuple_id, 0, sizeof(MIH_C_LINK_TUPLE_ID_T)); - // The LINK_ID contains the MN LINK_ADDR - link_tuple_id.link_id.link_type = MIH_C_WIRELESS_LTE; -#ifdef USE_3GPP_ADDR_AS_LINK_ADDR - link_tuple_id.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_load_3gpp_str_address(mod_id, &link_tuple_id.link_id.link_addr._union._3gpp_addr, (u_int8_t*)UE_DEFAULT_3GPP_ADDRESS); -#else - link_tuple_id.link_id.link_addr.choice = MIH_C_CHOICE_3GPP_3G_CELL_ID; - memcpy(link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val, &g_ue_ral_obj[mod_id].plmn_id, 3); - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id = g_ue_ral_obj[mod_id].cell_id; - LOG_D(RAL_UE, "PLMN ID %d.%d.%d\n", link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[0], - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[1], - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[2]); - LOG_D(RAL_UE, "CELL ID %d\n", link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id); -#endif - //The optional LINK_ADDR may contains a link address of PoA. - link_tuple_id.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - - mRAL_send_link_up_indication(instanceP, &g_ue_ral_obj[mod_id].transaction_id, - &link_tuple_id, - NULL, //MIH_C_LINK_ADDR_T *old_arP,(Optional) Old Access Router link address. - NULL, //MIH_C_LINK_ADDR_T *new_arP,(Optional) New Access Router link address. - NULL, //MIH_C_IP_RENEWAL_FLAG_T *flagP, (Optional) Indicates whether the MN needs to change IP Address in the new PoA. - NULL); //MIH_C_IP_MOB_MGMT_T *mobil_mngtP, (Optional) Indicates the type of Mobility Management Protocol supported by the new PoA. - - g_ue_ral_obj[mod_id].transaction_id ++; - -} -//--------------------------------------------------------------------------------------------------------------------- -void mRAL_rx_rrc_ral_connection_reestablishment_indication(instance_t instanceP, - MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - MIH_C_LINK_TUPLE_ID_T link_tuple_id; - module_id_t mod_id = instanceP - NB_eNB_INST; - - memset(&link_tuple_id, 0, sizeof(MIH_C_LINK_TUPLE_ID_T)); - //The optional LINK_ADDR may contains a link address of PoA. - link_tuple_id.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - link_tuple_id.link_id.link_type = MIH_C_WIRELESS_LTE; -#ifdef USE_3GPP_ADDR_AS_LINK_ADDR - link_tuple_id.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_load_3gpp_str_address(mod_id, &link_tuple_id.link_id.link_addr._union._3gpp_addr, (u_int8_t*)UE_DEFAULT_3GPP_ADDRESS); -#else - link_tuple_id.link_id.link_addr.choice = MIH_C_CHOICE_3GPP_3G_CELL_ID; - // preserve byte order of plmn id - memcpy(link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val, &g_ue_ral_obj[mod_id].plmn_id, 3); - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id = g_ue_ral_obj[mod_id].cell_id; - - LOG_D(RAL_UE, "PLMN ID %d.%d.%d\n", link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[0], - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[1], - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[2]); - LOG_D(RAL_UE, "CELL ID %d\n", link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id); -#endif - - LOG_D(RAL_UE, "RRC_RAL_CONNECTION_ESTABLISHMENT_IND num srb %d num drb %d\n", RRC_RAL_CONNECTION_REESTABLISHMENT_IND(msg_pP).num_srb,RRC_RAL_CONNECTION_REESTABLISHMENT_IND(msg_pP).num_drb); - - if ((RRC_RAL_CONNECTION_REESTABLISHMENT_IND(msg_pP).num_drb > 0) && (RRC_RAL_CONNECTION_REESTABLISHMENT_IND(msg_pP).num_srb > 0)) { - mRAL_send_link_up_indication(instanceP, &g_ue_ral_obj[mod_id].transaction_id, - &link_tuple_id, - NULL, //MIH_C_LINK_ADDR_T *old_arP,(Optional) Old Access Router link address. - NULL, //MIH_C_LINK_ADDR_T *new_arP,(Optional) New Access Router link address. - NULL, //MIH_C_IP_RENEWAL_FLAG_T *flagP, (Optional) Indicates whether the MN needs to change IP Address in the new PoA. - NULL); //MIH_C_IP_MOB_MGMT_T *mobil_mngtP, (Optional) Indicates the type of Mobility Management Protocol supported by the new PoA. - } else { - MIH_C_LINK_DN_REASON_T reason_code = MIH_C_LINK_DOWN_REASON_EXPLICIT_DISCONNECT; - - mRAL_send_link_down_indication(instanceP, &g_ue_ral_obj[mod_id].transaction_id, - &link_tuple_id, - NULL, - &reason_code); - } - - g_ue_ral_obj[mod_id].transaction_id ++; -} -//--------------------------------------------------------------------------------------------------------------------- -void mRAL_rx_rrc_ral_connection_reconfiguration_indication(instance_t instanceP, - MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - MIH_C_LINK_TUPLE_ID_T link_tuple_id; - module_id_t mod_id = instanceP - NB_eNB_INST; - - memset(&link_tuple_id, 0, sizeof(MIH_C_LINK_TUPLE_ID_T)); - //The optional LINK_ADDR may contains a link address of PoA. - link_tuple_id.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - link_tuple_id.link_id.link_type = MIH_C_WIRELESS_LTE; -#ifdef USE_3GPP_ADDR_AS_LINK_ADDR - link_tuple_id.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_load_3gpp_str_address(mod_id, &link_tuple_id.link_id.link_addr._union._3gpp_addr, (u_int8_t*)UE_DEFAULT_3GPP_ADDRESS); -#else - // preserve byte order of plmn id - memcpy(link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val, &g_ue_ral_obj[mod_id].plmn_id, 3); - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id = g_ue_ral_obj[mod_id].cell_id; - - LOG_D(RAL_UE, "PLMN ID %d.%d.%d\n", link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[0], - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[1], - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[2]); - LOG_D(RAL_UE, "CELL ID %d\n", link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id); -#endif - - LOG_D(RAL_UE, "RRC_RAL_CONNECTION_RECONFIGURATION_IND num srb %d num drb %d\n", - RRC_RAL_CONNECTION_RECONFIGURATION_IND(msg_pP).num_srb, - RRC_RAL_CONNECTION_RECONFIGURATION_IND(msg_pP).num_drb); - - if ((RRC_RAL_CONNECTION_RECONFIGURATION_IND(msg_pP).num_drb > 0) && - (RRC_RAL_CONNECTION_RECONFIGURATION_IND(msg_pP).num_srb > 0)) { - mRAL_send_link_up_indication(instanceP, &g_ue_ral_obj[mod_id].transaction_id, - &link_tuple_id, - NULL, //MIH_C_LINK_ADDR_T *old_arP,(Optional) Old Access Router link address. - NULL, //MIH_C_LINK_ADDR_T *new_arP,(Optional) New Access Router link address. - NULL, //MIH_C_IP_RENEWAL_FLAG_T *flagP, (Optional) Indicates whether the MN needs to change IP Address in the new PoA. - NULL); //MIH_C_IP_MOB_MGMT_T *mobil_mngtP, (Optional) Indicates the type of Mobility Management Protocol supported by the new PoA. - } else { - MIH_C_LINK_DN_REASON_T reason_code = MIH_C_LINK_DOWN_REASON_EXPLICIT_DISCONNECT; - - mRAL_send_link_down_indication(instanceP, &g_ue_ral_obj[mod_id].transaction_id, - &link_tuple_id, - NULL, - &reason_code); - } - - g_ue_ral_obj[mod_id].transaction_id ++; -} -//--------------------------------------------------------------------------------------------------------------------- -void mRAL_rx_rrc_ral_connection_release_indication(instance_t instanceP, MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - -} - - - - - - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_subscribe.c b/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_subscribe.c deleted file mode 100755 index 0e61802474..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_subscribe.c +++ /dev/null @@ -1,136 +0,0 @@ -/*************************************************************************** - ltmRALue_subscribe.c - description - *************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 1999 - 2013 Eurecom - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information - Openair Admin: openair_admin@eurecom.fr - Openair Tech : openair_tech@eurecom.fr - Forums : http://forums.eurecom.fsr/openairinterface - Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France -*******************************************************************************/ -/*! \file ltmRALue_subscribe.c - * \brief - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#define LTE_RAL_UE -#define LTERALUE_SUBSCRIBE_C -//----------------------------------------------------------------------------- -#include "lteRALue.h" -#include "LAYER2/MAC/extern.h" -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: mRAL_subscribe_request() ** - ** ** - ** Description: Subscribes the MIH-F to receive specified link event ** - ** indications and sends Link Event Subscribe confirmation ** - ** to the MIH-F. ** - ** ** - ** Inputs: msg_pP: Pointer to the received MIH message ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -void mRAL_subscribe_request(ral_ue_instance_t instanceP, - MIH_C_Message_Link_Event_Subscribe_request_t *msg_pP) -{ - module_id_t mod_id = instanceP - NB_eNB_INST; - MIH_C_STATUS_T status = MIH_C_STATUS_REJECTED; - - /* Check whether the action request is supported */ - if (g_ue_ral_obj[mod_id].mih_supported_link_command_list & MIH_C_BIT_LINK_EVENT_SUBSCRIBE) { - MIH_C_LINK_EVENT_LIST_T mih_subscribed_req_event_list; - - g_ue_ral_obj[mod_id].mih_subscribe_req_event_list |= (msg_pP->primitive.RequestedLinkEventList & g_ue_ral_obj[mod_id].mih_supported_link_event_list); - - mih_subscribed_req_event_list = g_ue_ral_obj[mod_id].mih_subscribe_req_event_list & msg_pP->primitive.RequestedLinkEventList; - - status = MIH_C_STATUS_SUCCESS; - - mRAL_send_event_subscribe_confirm(instanceP, &msg_pP->header.transaction_id, - &status, - &mih_subscribed_req_event_list); - } else { - mRAL_send_event_subscribe_confirm(instanceP, &msg_pP->header.transaction_id, - &status, - NULL); - } -} - -/**************************************************************************** - ** ** - ** Name: mRAL_unsubscribe_request() ** - ** ** - ** Description: Unsubscribes the MIH-F to receive specified link event ** - ** indications and sends Link Event Unsubscribe confirmation ** - ** to the MIH-F. ** - ** ** - ** Inputs: msg_pP: Pointer to the received MIH message ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -void mRAL_unsubscribe_request(ral_ue_instance_t instanceP, - MIH_C_Message_Link_Event_Unsubscribe_request_t *msg_pP) -{ - MIH_C_STATUS_T status = MIH_C_STATUS_REJECTED; - module_id_t mod_id = instanceP - NB_eNB_INST; - - /* Check whether the action request is supported */ - if (g_ue_ral_obj[mod_id].mih_supported_link_command_list & MIH_C_BIT_LINK_EVENT_UNSUBSCRIBE) { - MIH_C_LINK_EVENT_LIST_T mih_unsubscribed_req_event_list; - MIH_C_LINK_EVENT_LIST_T saved_req_event_list; - - saved_req_event_list = g_ue_ral_obj[mod_id].mih_subscribe_req_event_list; - - g_ue_ral_obj[mod_id].mih_subscribe_req_event_list &= ~(msg_pP->primitive.RequestedLinkEventList & g_ue_ral_obj[mod_id].mih_supported_link_event_list); - mih_unsubscribed_req_event_list = g_ue_ral_obj[mod_id].mih_subscribe_req_event_list ^ saved_req_event_list; - - status = MIH_C_STATUS_SUCCESS; - - mRAL_send_event_unsubscribe_confirm(instanceP, &msg_pP->header.transaction_id, - &status, - &mih_unsubscribed_req_event_list); - } else { - mRAL_send_event_unsubscribe_confirm(instanceP, &msg_pP->header.transaction_id, - &status, - NULL); - } -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - - diff --git a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_thresholds.c b/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_thresholds.c deleted file mode 100755 index 4176ef60cf..0000000000 --- a/openair3/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_thresholds.c +++ /dev/null @@ -1,313 +0,0 @@ -/*************************************************************************** - ltmRALue_thresholds.c - description - *************************************************************************** - Eurecom OpenAirInterface 3 - Copyright(c) 1999 - 2013 Eurecom - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information - Openair Admin: openair_admin@eurecom.fr - Openair Tech : openair_tech@eurecom.fr - Forums : http://forums.eurecom.fr/openairinterface - Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France -*******************************************************************************/ -/*! \file ltmRALue_thresholds.c - * \brief - * \author WETTERWALD Michelle, GAUTHIER Lionel, MAUREL Frederic - * \date 2013 - * \company EURECOM - * \email: michelle.wetterwald@eurecom.fr, lionel.gauthier@eurecom.fr, frederic.maurel@eurecom.fr - */ -/*******************************************************************************/ -#define LTE_RAL_UE -#define LTERALUE_THRESHOLDS_C -//----------------------------------------------------------------------------- -#include "assertions.h" -#include "lteRALue.h" - -extern unsigned char NB_eNB_INST; - - -/**************************************************************************** - ** ** - ** Name: mRAL_configure_thresholds_request() ** - ** ** - ** Description: Forwards the Link_Configure_Thresholds.request message ** - ** to the RRC layer. ** - ** ** - ** Inputs: msg_pP: Pointer to the received message ** - ** Others: ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void mRAL_configure_thresholds_request(ral_ue_instance_t instanceP, - MIH_C_Message_Link_Configure_Thresholds_request_t* msg_pP) -{ - unsigned int index; - unsigned int th_index; - rrc_ral_configure_threshold_req_t configure_threshold_req; - MessageDef *message_p; - MIH_C_STATUS_T status; - MIH_C_STATUS_T global_status; - int result; - MIH_C_LINK_CFG_STATUS_LIST_T link_configure_status_list; - - MIH_C_LINK_CFG_STATUS_LIST_init(&link_configure_status_list); - - message_p = itti_alloc_new_message (TASK_RAL_UE, RRC_RAL_CONFIGURE_THRESHOLD_REQ); - - memset(&configure_threshold_req, 0, sizeof(rrc_ral_configure_threshold_req_t)); - - // copy transaction id - configure_threshold_req.transaction_id = msg_pP->header.transaction_id; - - global_status = MIH_C_STATUS_SUCCESS; - - // configure_threshold_req.num_link_cfg_params = 0; // done - for (index = 0; index < msg_pP->primitive.LinkConfigureParameterList_list.length; index++) { - - status = MIH_C_STATUS_SUCCESS; - - // copy link_param_type - configure_threshold_req.link_cfg_params[index].link_param_type.choice = msg_pP->primitive.LinkConfigureParameterList_list.val[index].link_param_type.choice; - - switch (configure_threshold_req.link_cfg_params[index].link_param_type.choice) { - case RAL_LINK_PARAM_TYPE_CHOICE_GEN: - memcpy(&configure_threshold_req.link_cfg_params[index].link_param_type._union.link_param_gen, - &msg_pP->primitive.LinkConfigureParameterList_list.val[index].link_param_type._union.link_param_gen, - sizeof(ral_link_param_gen_t)); - break; - - case RAL_LINK_PARAM_TYPE_CHOICE_QOS: - memcpy(&configure_threshold_req.link_cfg_params[index].link_param_type._union.link_param_qos, - &msg_pP->primitive.LinkConfigureParameterList_list.val[index].link_param_type._union.link_param_qos, - sizeof(ral_link_param_qos_t)); - break; - - case RAL_LINK_PARAM_TYPE_CHOICE_LTE: - memcpy(&configure_threshold_req.link_cfg_params[index].link_param_type._union.link_param_lte, - &msg_pP->primitive.LinkConfigureParameterList_list.val[index].link_param_type._union.link_param_lte, - sizeof(ral_link_param_lte_t)); - break; - - default: - status = MIH_C_STATUS_UNSPECIFIED_FAILURE; - break; - } - - // at first error, exit - - - configure_threshold_req.num_link_cfg_params += 1; - - // copy choice - configure_threshold_req.link_cfg_params[index].union_choice = msg_pP->primitive.LinkConfigureParameterList_list.val[index].choice; - - // copy _union - switch (configure_threshold_req.link_cfg_params[index].union_choice) { - case RAL_LINK_CFG_PARAM_CHOICE_TIMER_NULL: - configure_threshold_req.link_cfg_params[index]._union.null_attr = 0; - break; - - case RAL_LINK_CFG_PARAM_CHOICE_TIMER: - configure_threshold_req.link_cfg_params[index]._union.timer_interval = msg_pP->primitive.LinkConfigureParameterList_list.val[index]._union.timer_interval; - break; - - default: - printf("ERROR RAL_UE, : mRAL_configure_thresholds_request unknown configure_threshold_req.link_cfg_params[index].union_choice %d\n", - configure_threshold_req.link_cfg_params[index].union_choice); - status = MIH_C_STATUS_UNSPECIFIED_FAILURE; - break; - } - - // copy th_action - configure_threshold_req.link_cfg_params[index].th_action = msg_pP->primitive.LinkConfigureParameterList_list.val[index].th_action; - - // configure_threshold_req.link_cfg_params[index].num_thresholds = 0; // done - for (th_index = 0; th_index < msg_pP->primitive.LinkConfigureParameterList_list.val[index].threshold_list.length; th_index++) { - configure_threshold_req.link_cfg_params[index].thresholds[th_index].threshold_val = msg_pP->primitive.LinkConfigureParameterList_list.val[index].threshold_list.val[th_index].threshold_val; - configure_threshold_req.link_cfg_params[index].thresholds[th_index].threshold_xdir = msg_pP->primitive.LinkConfigureParameterList_list.val[index].threshold_list.val[th_index].threshold_xdir; - configure_threshold_req.link_cfg_params[index].num_thresholds += 1; - - // Fill ConfigureThreshold_confirm - if (link_configure_status_list.length < MIH_C_LINK_CFG_STATUS_LIST_LENGTH) { - memcpy(&link_configure_status_list.val[link_configure_status_list.length].link_param_type, - &configure_threshold_req.link_cfg_params[index].link_param_type, - sizeof(ral_link_param_type_t)); - - memcpy(&link_configure_status_list.val[link_configure_status_list.length].threshold, - &msg_pP->primitive.LinkConfigureParameterList_list.val[index].threshold_list.val[th_index], - sizeof(ral_link_param_type_t)); - - link_configure_status_list.val[link_configure_status_list.length].config_status = status; - - link_configure_status_list.length += 1; - } else { - LOG_E(RAL_UE, "MIH_C_LINK_CFG_STATUS_LIST overflow for send_configure_thresholds_confirm\n"); - global_status = MIH_C_STATUS_UNSPECIFIED_FAILURE; - } - } - } - - if (link_configure_status_list.length > 0) { - memcpy (&message_p->ittiMsg, (void *) &configure_threshold_req, sizeof(rrc_ral_configure_threshold_req_t)); - itti_send_msg_to_task (TASK_RRC_UE, instanceP, message_p); - - mRAL_send_configure_thresholds_confirm(instanceP, - &msg_pP->header.transaction_id, - &global_status, - &link_configure_status_list); - } else { - mRAL_send_configure_thresholds_confirm(instanceP, - &msg_pP->header.transaction_id, - &global_status, - NULL); - - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void mRAL_rx_rrc_ral_configure_threshold_conf(ral_ue_instance_t instance, MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - MIH_C_STATUS_T status; - // This parameter is not included if Status does not indicate “Success.†- MIH_C_LINK_CFG_STATUS_LIST_T link_cfg_status_list; - unsigned int i; - - status = RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_pP).status; - - if (status == RAL_STATUS_SUCCESS) { - link_cfg_status_list.length = 0; - - for (i = 0; i < RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_pP).num_link_cfg_params; i++) { - link_cfg_status_list.val[i].link_param_type.choice = RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_pP).cfg_status[i].link_param_type.choice; - - switch (link_cfg_status_list.val[i].link_param_type.choice) { - case RAL_LINK_PARAM_TYPE_CHOICE_GEN: - memcpy(&link_cfg_status_list.val[i].link_param_type._union.link_param_gen, - &RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_pP).cfg_status[i].link_param_type._union.link_param_gen, - sizeof(ral_link_param_gen_t)); - break; - - case RAL_LINK_PARAM_TYPE_CHOICE_QOS: - memcpy(&link_cfg_status_list.val[i].link_param_type._union.link_param_qos, - &RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_pP).cfg_status[i].link_param_type._union.link_param_qos, - sizeof(ral_link_param_qos_t)); - break; - - case RAL_LINK_PARAM_TYPE_CHOICE_LTE: - memcpy(&link_cfg_status_list.val[i].link_param_type._union.link_param_lte, - &RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_pP).cfg_status[i].link_param_type._union.link_param_lte, - sizeof(ral_link_param_lte_t)); - break; - - default: - assert(1==0); - } - - link_cfg_status_list.val[i].threshold.threshold_val = RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_pP).cfg_status[i].threshold.threshold_val; - link_cfg_status_list.val[i].threshold.threshold_xdir = RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_pP).cfg_status[i].threshold.threshold_xdir; - link_cfg_status_list.val[i].config_status = RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_pP).cfg_status[i].config_status; - link_cfg_status_list.length += 1; - } - - mRAL_send_configure_thresholds_confirm(instance, &RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_pP).transaction_id, &status, &link_cfg_status_list); - } else { - mRAL_send_configure_thresholds_confirm(instance, &RRC_RAL_CONFIGURE_THRESHOLD_CONF(msg_pP).transaction_id, &status, NULL); - } -} -//--------------------------------------------------------------------------------------------------------------------- -void mRAL_rx_rrc_ral_measurement_report_indication(ral_ue_instance_t instanceP, MessageDef *msg_pP) -//--------------------------------------------------------------------------------------------------------------------- -{ - MIH_C_TRANSACTION_ID_T transaction_id; - module_id_t mod_id; - MIH_C_LINK_TUPLE_ID_T link_tuple_id; - LIST(MIH_C_LINK_PARAM_RPT, link_parameters_report); - - mod_id = instanceP - NB_eNB_INST; - transaction_id = g_ue_ral_obj[mod_id].transaction_id; - g_ue_ral_obj[mod_id].transaction_id += 1; - - memset(&link_tuple_id, 0, sizeof(MIH_C_LINK_TUPLE_ID_T)); - link_tuple_id.link_id.link_type = MIH_C_WIRELESS_LTE; -#ifdef USE_3GPP_ADDR_AS_LINK_ADDR - link_tuple_id.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_load_3gpp_str_address(mod_id, &link_tuple_id.link_id.link_addr._union._3gpp_addr, (u_int8_t*)UE_DEFAULT_3GPP_ADDRESS); -#else - link_tuple_id.link_id.link_addr.choice = MIH_C_CHOICE_3GPP_3G_CELL_ID; - - // preserve byte order of plmn id - memcpy(link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val, &g_ue_ral_obj[mod_id].plmn_id, 3); - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id = g_ue_ral_obj[mod_id].cell_id; - - LOG_D(RAL_UE, "PLMN ID %d.%d.%d\n", link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[0], - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[1], - link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[2]); - LOG_D(RAL_UE, "CELL ID %d\n", link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id); -#endif - - MIH_C_LINK_PARAM_RPT_LIST_init(&link_parameters_report_list); - memcpy(&link_parameters_report_list.val[0].link_param, - &RRC_RAL_MEASUREMENT_REPORT_IND(msg_pP).link_param, - sizeof(MIH_C_LINK_PARAM_T)); - - if (RRC_RAL_MEASUREMENT_REPORT_IND(msg_pP).threshold.threshold_xdir == RAL_NO_THRESHOLD) { - link_parameters_report_list.val[0].choice = MIH_C_LINK_PARAM_RPT_CHOICE_NULL; - } else { - link_parameters_report_list.val[0].choice = MIH_C_LINK_PARAM_RPT_CHOICE_THRESHOLD; - link_parameters_report_list.val[0]._union.threshold.threshold_val = RRC_RAL_MEASUREMENT_REPORT_IND(msg_pP).threshold.threshold_val; - link_parameters_report_list.val[0]._union.threshold.threshold_xdir = RRC_RAL_MEASUREMENT_REPORT_IND(msg_pP).threshold.threshold_xdir; - } - - link_parameters_report_list.length += 1; - - mRAL_send_link_parameters_report_indication(instanceP, - &transaction_id, - &link_tuple_id, - &link_parameters_report_list); -} -/* - * typedef struct MIH_C_LINK_PARAM { - MIH_C_LINK_PARAM_TYPE_T link_param_type; - MIH_C_CHOICE_T choice; - union { - MIH_C_LINK_PARAM_VAL_T link_param_val; - MIH_C_QOS_PARAM_VAL_T qos_param_val; - } _union; -} MIH_C_LINK_PARAM_T; - - * typedef struct MIH_C_LINK_PARAM_RPT { - MIH_C_LINK_PARAM_T link_param; - MIH_C_CHOICE_T choice; - union { - MIH_C_NULL_T null_attr; - MIH_C_THRESHOLD_T threshold; - } _union; -} MIH_C_LINK_PARAM_RPT_T; -#define MIH_C_LINK_PARAM_RPT_CHOICE_NULL 0 -#define MIH_C_LINK_PARAM_RPT_CHOICE_THRESHOLD 1 - * - */ - diff --git a/openair3/RAL-LTE/Makefile.inc b/openair3/RAL-LTE/Makefile.inc deleted file mode 100755 index 19b9f286af..0000000000 --- a/openair3/RAL-LTE/Makefile.inc +++ /dev/null @@ -1,43 +0,0 @@ - -RAL_OBJS = - -ifeq ($(ENABLE_RAL), 1) -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_header_codec.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_msg_codec.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_primitive_codec.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_F1_basic_data_types_codec.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_F2_general_data_types_codec.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_F3_data_types_for_address_codec.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_F4_data_types_for_links_codec.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_F9_data_types_for_qos_codec.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_F13_data_types_for_information_elements_codec.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_L2_type_values_for_tlv_encoding.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_Medieval_extensions.o -#RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_log.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C_bit_buffer.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/C/MIH_C.o - -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_action.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_main.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_mih_msg.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_parameters.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_process.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_rrc_msg.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_subscribe.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_ENB/SRC/lteRALenb_thresholds.o - -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_action.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_main.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_mih_msg.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_parameters.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_process.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_rrc_msg.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_subscribe.o -RAL_OBJS += $(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_UE/SRC/lteRALue_thresholds.o -endif - -EXTRA_CFLAGS += -DMIH_C_MEDIEVAL_EXTENSIONS -L2_OBJS += $(RAL_OBJS) -L2_incl += -I$(OPENAIR3_DIR)/RAL-LTE/INTERFACE-802.21/INCLUDE -L2_incl += -I$(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_ENB/INCLUDE -L2_incl += -I$(OPENAIR3_DIR)/RAL-LTE/LTE_RAL_UE/INCLUDE diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/README.txt b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/README.txt deleted file mode 100644 index f3bab3c129..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/README.txt +++ /dev/null @@ -1,12 +0,0 @@ --------------------------------------------------------------------------------- - Scenario used with rg_mih_user.cpp (MIH user run at the Radio Gateway side) --------------------------------------------------------------------------------- - --- Activate/Deactivate Unicast resource 2001:0660:0382:0014:0335:0600:8014:9150 -mih_mscgen_page_10.png - --- Activate/Deactivate Multicast resource FF3E:0020:2001:0DB8:0000:0000:0000:0043 -mih_mscgen_page_11.png - --- Activate/Deactivate Non-RB-CONNECTED Unicast resource 2001:0660:0382:0014:0335:0600:8014:9153 -mih_mscgen_page_12.png diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_0.png b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_0.png deleted file mode 100644 index 5756f2173d023a418928239ae971ace90d1ddc7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57361 zcmdSBcUTi|w>COpK><YtM3JJ>M5-X7bZiI#QL5C4f|1^PRm6sZ)EG*F1(2@v5(ppy zp#?>V^j-sm009DloJsJv_xtYa`{&#HT<6+n{$Ubko+;0I?sc!V?v+<}ZfhN4<z)o` z;E?vM>jnUD0NmZzet;SLL$W>B4gjYC?dzIGekt>VHa?#u`+<>(D@C7t^k$R#6xwsK z#23RGN?|Xre|kdLydYL`KvB3P^;E-_EW08&005*((Ng&td%#z9&fT5P)Bp1wjq%0x zz-8|{q8mL1+CaW!4RW|gdRBS^(D<$kUghnn=VzcJAsCMDvh3gE_r$U@`x#;#cjjc6 zfiM#UkY<M!L9Jt^hLZ$OLWSXnncVEU(v@qPWfIumoc!pnHqv~H$uD&ynzk`QwE)ls z6E{K>j_!5d^7a9i3|3M)Hk8z2gP3Y9-b>GS?F*{O4=oOe@ttIOtUW5j97@?!e5R%u zF8nmjMiiK7UB%PNyTAL%B9~KZCh>qq;8VvfY6cTLI830yH1Oc*ut&l&%bHIvE9^Za z&!piy_Crm29Z+RE&cxJt2EzuJbLXxLLjRDT<ooRhtX>MvoftmA4gg-Qp+|r|QHASe z156sNQ@-B&WL!e01IL8`bV)jYNQ=yJ9qka+2k;Xj*<q+WPqqM{&oGwvX(?rVKVuen zZP`vUb{@Yw$oLEVU++}<V1{vrnZh{BclNAe$%1M6`Lxxxy}P4boWb`p(RcX>^l7-W zVYj?Wfg6reU#$?OtC6NPM#e#l1}ZsuP0o3x0&wv+nV+GMOxw9E$7<UKAjy_)f52li zxj}XH6G0~<4RP22ljJB|i!S>_LOlEOIQF-{Ho;wSye%+jac*S5z)&1Jdj6GcsL3+_ z-kB#-Vc^+ekEEp5qF3<AJ_n)M(}*G;oF2?z2^+L6tpIJe*n7~8&zF7?fbZkP&{KEO z`;N#;TLQAWPw5<zpK!24sW=lL{@68M84sGHlAOz(qS>AB+1&2EzIX0t<(>Xq51b#< zE<NScWOP?Q$Yk)#a?RrU77mB&y<5wTV2piP2aUfYSGV2bME(`-36-fJ(rU=bduE#O zc>Hz<ZDktQ`=qwyJ>%G<l43mVR}oXG$<~C)MuDzARG!;9_R}ygMIo@oF(@P?Bse&g zf1l+`#)N@3d?gH4NQ01Vb*3Z^mez@jd!l-|me9!99@o&7S<3S<Kb?*wmc(2!<YV!Z zZ|g&TW}{Go%FJ~Q-tY1$h5&uKfMAd9X{q1N9Yy#=wI=67t3mA{&#?EB95%PN)|;AM zaB!&7jh?<yF_jl5t+DOb%Er~J_baVZC=@@Hjwt31+s(*)1k?VRID)zc%8Bi8r&K7d zON#MoJJ~?{7PZUp6O4W_&D1I1Iy{raokqVX3*+z{l|4Wr)pz#-K;Y)ij==NL@$vC_ zjS*W>##O^^st82eoKV@~xrt<$6Ht7AU}bv#+{o2|-Op&nz#WZP<=vwdr%qzNHv9#g z|0d3)L18TP(cE&kw$<3Ljl!{A)6m-y(_*5nx-9TH4u@Mc`8hE0sqUWfQWJ~lR<1_F zUj^xg8R1wt%?QM|eUFp>&JP5;ihX~*LpUPNep2^&FxAB7m%q4$Dy|tXQUKA}-%GI_ ztNBd!V;@I{f;QYdY|teI8oAKknYh2^%PqYY4gcbrUAknE>~Q;eaiEWK+*8~{FDjQp z&ZtA*z6BJF9;V-F8c(1|C}a)+TUsgO$sG!n?I}{&i0xT-Af)*n&SObqS!5jLtFEq| zY!doC*6(}D&z^p^n_V%lbux-fiY7Flq?bN@$GYdsOR?U?p!?$iV{+L0k~9{j3C8%F z<Y^oVwCkczX}*xaNijjctt2j=0h1r>4Vp2+t!PPsu=O#<kxFDTS!8P%U0+O=enk#1 zTq)44g07gnFPahnct;qARIY#<ne6Sug>DWyNQu`%61|`?<@!BwPQC$F$0p{=66drN zwTF!F2;8Jfj_HbsME`j^E*>iDx~$js%;=|Ym}u|ToBZA#j$I4pEubM(L#aL^Rt*+= z_<eia$>_pIO4G#9fJY373$Vcn_Q_HSokdYO(+LWDyjoXztmOBwcZ%Ud!_<1O@ugYp z>||On%u7Q?Ai4>B&|kjkFX$lj9%;676Q2w0+qG`cT+{TygJHV|YpJQJJ-6A|*-=wI z0)%~MtoStL=%$A!o;QuV`<w;<77rSml_%Q?4U{E~X)_+ZgY(_H+|QJzO&?@;QlLJ2 znE~EM|GJ3i$4+eO<NjJWa7b>~)c-GcHvg{Nz{+9bcUj$nCY}|cE<!qJ%~28H3}?sM z$vu&Z0HI56Dz+zXyvUTmz0G=F++T)u{1r~8k-hT-!%u4{o5amOe0n)<$x26pr68Q$ zL-Yg2$SK6u+L>Z`gU`qMouGb3M{D5GX#$F9y1e~5N2&len|t{@I8V%UHu3oSJ6yZ% zi}2OpAp;*}XvTF}sc(IYadL5jq&g~}wwm|OScvo4aSpFtu+<n}GoPt0mJGH&y)tOg zyUmi5V4F1L^}ySLI}cL`C7CI&ag9`$@1dLY<KD$y+8cLQgkBlX04*RRb~ZQm0EGGQ z)$_Sxe@K{*&@MAW<B09o-`P5{PZ<yW03nw`xuVQkes=fKimVaaGF(I?O4kh|XTe`a z4uTOj6EJmS{!;+&8fc`LVH%a<>2ummih)OAH}}pCrsr<=IE83as(-c6LAod}mT$YK zS!8>Q1Y#n?u-(oey>H`vEbEwRPq{O&E>t~ZU8y3wdMQp;<~Y8{XocF^trR}Z)L=7> zDol1#@_b-p;az>eyntY;-7azgj!~9oYkxWISA)R_MmMcmxn3Mxp3QU&VFLc~wCJqL zcK@}$U$FJOCqB8o913yi$toeVooy0n^wU*b$Y0tOId=@MtoH3bJRs_enGW0-g+g@& z1D#@BP_K4&*<HJ|<#Y>kp=_aCD(EjY%=#9<bWvRX$CjT8=yR-3vRl5MboFXyy%VNZ z@z>KEg9`w%qx=_jRf9uAIleEENTAKT$?cLm4IywP$+9E2*@STPnF0WF*+uY8a=D#h z*gXIYC98&>#_nQu?WvVF(0jWO0?z7xkCJp26funAo;zmvh0S~GXqhRk3_K(ghv8#u zA`3gVnhNYK<@#k{fe47b053-Jp{mVs>k?4?BST(aKa=N3;`XZ2ag<xRA%6hr9}FJj zW}l<Ic3P9qLPuW=%A)7W>KbB;j46N!!sFQsN3qvI4g#TUPH!ayVX`eaSaYLb+Jx9G zjqgrO^wTX(<rYpw!k<m&Nq>pPNOI{y;)}Q5v`uJ<c2#E~e}33Dciy%%gctA$|8-zt zit>*hqV#`s5MFs!MUdeGp?7$e=6Y0>OO1bSe%OB9I<KI8=R!6>Y-QZt(j(TgP=7Pk zC+Yi^El!<BJvnFZs9=UsqTR(8*q+CHBrA#J!F3N>QU&&fiIf6#N>x7SQU<!Uh1J5@ z20z;7-I_liSOw#%N;+PLNG+hDJQ_bNiuyJUFaYm;1_LY4KRsO)PaCXMQm%L(+`=pv ze67|!zqdyMrk3BMR9o@)LHmN%6a3|Tb-GOF+hcRZWVz4v&Z@=PN!vSSL06a&J@VxE zVq|gOW=83h>jP~}V#{y4m30UHk%d2K5XmurksRbAN^_T{dmSOD!Lt38FHN?7tXR@! z5xZt)oh{8%VY<JlTlaC!HnZPz7~QA<KqH(^_!&F9H&a|Np;=D)9s&`dC1?5DPm^K? z=X?iBf=YNINE2*Mhh|?|vk)UPnSou_#jB_<0W)a(F54hJKGOWl%p$I}K=&rk+Q-jG z(vOumPAxBWiZo<%PpUivguQH$LWiT~C$U@mTW~rVXy2@grFeS>8+#-9qf^A<TRm}t zf2eQS9x;ch?J~ehLqGjmd4*}7LDOREW1ilaxsD{?OXZv&skbBj8WJ-OjcG>&8Fg<n zKYqT;8?<t&##F?MNVmO3D}|?Cha})M_D+uT;NC~y8;GngjqME$bJ-m_U^S|D^z@Yd z&uz!TA#MdRA(bzA$#y$H46TFVX-B-HtT&*)I$Ix{^NR69vI}+WKtDqPF*z9>yyPKZ z*QZ(1lzCjChQ6QCQ`Exs?xgSu?<ppXrbHn5tn`sg{CGX?`engyZQq}nRvk%sPvlW` z+s=fkZF{xL0RM>x4Ca4agE0^Pm3FNzPER*|zseN0Mpa_W<mGmhdZ?PZIxgy|>ABD& zF4Xcq>f$IO2^Dl;$+{}BVC^hrW1#!Q6iiic&cFf}9lkyM1i1@Mw}XR&u{*vGbeW>% zd;=To$6^~u_Z}I(u8>7mbFDp)6F3>(_M+^e%;A=wRTV5VDU3H-DZfYoDF=w+Dff{h z0t-V8n%zSm-%sbYahU8qf>+UViZ@kAWH*<Iz7i!SXj6F4?R5!FW13-28d~#|?~jqZ zLyCGT-HDj)G+W5W^dwiiQ&UcJc<WCWh&zAUW0S(|pZl@LksD+ZmG*W1Lwy5xWPJzt zflt&$ig)sKe1qlBg1PII-#tdxsADJVR!%$(S?E8m5jSw~27ZA3z%Co%hfhyR?Zs?E zOgg6_(h0qesUbGPbyv5R`<8=yCF<K+w$t1~*a<^$TW68XP60a6wg5o8?2K$0kLg{9 z27Ix>F4$T3&iwfCP;PPnXLaS<)``sv#I94@vh|CSp`RR0!kBkG$T(Sjg&n}~_Z=rz zK<Tp|v=&q{b=vOa{3}ecPe_w>gF;g#*U+as{GM)}-_g3GsV7%tw%_=+4ue5nCMut@ z5A-5*2Gw3b19>GB3e{x7@B>K`An}?yQwy4c*EGqG{reIaB^=%hjA&$FW|B_c-?bTW z|7{fUz(m;|jX3J|U!tRd`8PVXjoA6<_$Z9dggEFIx;d%e@D^o|OgmubFtiD}L!yhp zugF-x3_Omd^morn^_mc_;l*D=0cL)@XW?t-?0s_C^j@qgU#nBQeAF4cr@eQzokU3S zZ$_ie82e3rVYWp4U2}$WlpXw{UapC<l<rVc-r)yGl(Kqx3DlePMkKtnMd-~Ix8T7! z?0Qas5mVm^VV+^>x8;XV*$xL^&FJ&NX~G+VEHTSx^dLltImfY8(n}G-D=6@_fq~SW zC7*a+34S|V{keX8lUse^bO`AU<>im+KV?#3rGIf^Ey{m_v6zGIQr)++zg#&vs_D!m zO9G>Pkl|~|^z*CHibw4Yw<K&UWsc$ET-$F1FuCo^5BF+EG5<$Q^$Dcrl|qvW1=4}g z?L}(qeK?i!N>kOl`rIqA4VOZy{Lv0A$#aG~;qzL^R~&m(SN@$<(8tMy?fMEJZ2#`9 z{cqn%Q&`_p^%UN5vGkKxL&_A1e}#3JzxFR#>e-Z-3#!T1b2YQMrtAaG#85qhBZR3A z64z}`JQZ4zd13Rib??5hfTuFyt|F(-!w+VBj13}=$yF6wf633QJ{x4G&jgIH(y6$H za%?Z{@`7>)lZv4;H7~Y!%is{nVSU1UCy$dIk$hsRXrE?Dof+0or{y=<OB`7rV*DFj z!UF(HHyNiFWydXJvm1FJ+$M@#xSPUa+@)(GYKmqSodK4jH8y9>^s(2Q9rUN6(y1lC zBZJx^$nmS76CQd=N6npS5JktJvClDyvCUhh+<fBpkL|r_8PThM>PYdrk?!r@r&v|5 zBroggqwK+J4n@$<aw+Ryz@gMZ(g)M3+nG9rM!N?1k}LLM<q#rE7J^USNqQcwOKGa8 z1Ay9eI;9=~NiP_`J-;8ZQ|v@Lu3EZI;aZD?ap@o}-pR;2N5?_?P+1O+0o4J<A){ub z=U2OpnE(*Pz}Mro0Nx^jK$t)Gr)%y3<#j_awvRGmR+#g{rKn^r;;wTg$LXjmy^(2T zTg2@B4Bc1V$c|I5QSDW~1D117Pt_xt0gZ=48)}dJhAdq70U9NwO;qnnlPim~^u2ED zjaR`_G4-AMQ9*PB>5`|zo@(JVhpY33DaDKw{*(y_drs*BacNja12tr)?}qstw!VDa z)D&(Kb{I?Rl&5DTR0C855X8gyrNW=UpC7%Z?cT8HBS3A=KUlLWjRS7&AXx=0c!_h? zg}6X;cu*nI|H*_IZrw3}f8DW!T<(iK02c^Mp1q3wa=f%;uH5%ZFFZX=UMo8<iYlLn z`cq(WaVj~0m&;<4eY$nRLgtEuTDiHtzfAso^~ZhpW#~CFko0O~{wLbKb8e(n3U`Gj zpGVALsnEyf^2#`Nf#P?U7EP@Pnh275;7Y)lP(()8^r3dB5k6)9$HJ_yKdX3iu*_SB zsaxJ%IYLnU=Bw@37Q=mAqr+&5%6rNyiX5T`-l5|o+`EcKj>N}WgBcBRFo+4uSEXlE zmX(>Sv-H?fpAJmQzwMZWn3NfaE#fnfhqD3?xAZIB68$`DQ8f*N3{6rGs8CKSe}lRc zB2YPLedWlur0sIu45EmF48Nt+*FH7?$ZrJKR_(&p*48?47^Zbs91##G7mcx1C{m{q ze&jXTHP#_e#{_#@-4%wdx1`~F4L78t_ju^M<3>_e8&wZQH4q5!^S!G_lhnKs?)l9- zVz|l$U!HvcAoCDh0V6(v{rpd2=R7<~tm~J*`Q3S>o|R87*G(zN?YN&fp$knsC1sy} z_CpZlZBWTX*j`9;c&U!LdNuSLwJG=OkJqc4!I^I}r#KHH<hsdw0Jr1x5QQecc)-ht zD|sPdBr0bxX%RysV0&D*Ci%vhu1Fh(-f8D1dJH~mpKAu`UsIPnMF`6){ik4Ej_f`+ zE0MVl0DdRw!#D@@8my-MtVn;bUdZx7Z8&0Mb-d9wYwB7NwgBPu5>vG)4V8bg6NJg& z%}_q5qxO&#Q;v)+o$F{>T|M6Z(zYX;06ymQZmcfJY7(TcHRjdt_-or;g?sA5?SzRf zZkRb+bc3^qh0Lq3`B0Gr^s<#TFU7VEXX{P4S<~0L$&J7BtIKxSl%Rdn!oA06qy{Z` z_Ysg;#3}^3T?1;~O+3|iUz&ck6>U7vwd3_f(qVoSJot}!Fx+B+2R6H~$x+)(Mll#x zn)^;!obSvA+G)vx@oxY?{~w6<e=u(Pj$7fZX2E*szTx&10Tegt1kb%}^{%mBWy_lR zK4%0+MI(+TvfsENj8*)YpMA-z-yHy?>#v0|0hhbBLs0573L!HDS$0iCxrU{FN*J={ z6gq0Wci@F8(zuFi)cPrF)7^Hsf8hsz8I@KL)^0NrUbi`6m2rfoxZXLvZc)xoY>$LN zH&&U0m3Zk^(sbu|@|m%zSc%1PIsLV>p1waalHx8D2xymD%c;4`VmqYY{-F*B5xhyD z$$p>%S8c?6A*-6_n31z(sCOiZdc82=_2#(eI8TI~iD#!KqWhH0CGy$kSe6TLzE?SV ziC8p-^eQKBTI`s~!y$KeCLk?}j<w~lKN+UWv^F;8{Z`;FxS-#IHlH$REZ#Wb=Fyb7 zoGlj&9h9Fd4a&S>BU@)i2_ea?Z*7B!Ie!jZKlOB$V0BBH!g0y(RrI_aLHcG{@A>8K zQ@qP|KI_yG-JEg7RJm$}74{wJ!GatywVaPozEKctLohT7m=4tdfDRbAQo_0#lD`W_ zs$x9U^KFoosXK?F=5tgO_*~Bwujc95W$WeiH64td9*!j4@X&~AMw$}qG2&?adL$Z5 zdKDBD6nz4K%Lpm)*(577I`axusGFJ{kL;Ejft*KVzm68xw{*T>rhmk9Flx<RwJcPg zxDrZeaZ;5lP&us78#&>k;+-e+gY$(ixDxq{Guq~wVNvl7LCTMGUVZk<p9BGd<fl7K zwg$ZD7Drj_QosNJcpcoV9Op4gQU21;xAG&OBpOPqBHvt@Omr#T*v&&Laxsbv^NgB; zhVKvwlSW!z^PS%}xJjj^EP{?}=EbZ`<)i&4()2Hl@1IG;(3q5jY1bGjwAJQN07!~Q zj0LL*fK0W3eLpbb^)GC+xJ4cSUV=`g=x^K<wY<Hp%Kp8nsj2q~0HoA1DBK~?b$plg zTay7g<rx``G=*`bI!ucRaFe6E7NGNR;0^%j(k%+m5K<XG3f%AbpJk#Mb+VNC5DW`6 zDt1^8sa6J>=!(H4;yAn}fy1MO4Kiwc?u~5k9m|Z5WLp{J{O=pZeKG);xndC1nZE51 z!RI!!t^Es^*slf2o_m)oHr(lDOKv!ZSYmDe-n?FR+rwzZ4(arGC~~lBCBV>^mjJFY zXHR<mJJYOvCpxxwZrNc)YbpV6Hx%c~9WVI}Du?^fq<F2NUBon_$qqUHV=k35LP6}I zwQ8(WwQW%1n3=O<7II|p;78Uu#NkI{pj#fN6N@l5gh4tkH}5vG%G}dxjh2{%D$g{D zH2p1zI)ynWS(FrhxFvVU?^_m+=0}y66%)5CoeOn6CRSkG-JI(Z{yj!C>u`{(C)0!W zk*iVt`=>h(`6Tuw{Z`<GEyO7lBv!<WyMpO@zPXGM`CyqWm^U;l?SuGycaikYad2`t z=wQ7>n@TR5SKIzt(sAD|z#B2BI@~!owmBhAGT4Mq_DYSi03&+-^a5F?_`m?|<pAOL zYEW6Cz24^0tf6JGlMSa@C4(Ie5e{7~>+XhIVl1#49z(vlqg^K;Rh0fDK_G039;b%M zx8qH4^7Xj+Kb$J<-nxV)1-umD@TC?^``Qb$yz^ZT_(p?rQZCzDTZ^8w!O|VVH=UaB zvQRPe#DJtL$D*wZ+p_CRb+~GXi>JWHy}tM`-O*)|QDVtt>p}8_oR(SsnW{eL6GCPE zra5#Y<R##D0T0Gq^swKr#Fr}b*h72Ae-!*gphI+R;AO>8=|K(vaBZSPFSw;?($jEZ z!SPNqRruq@b<b5G{iLR7N-F$d%_*aVSMn~^pOLZeO>rQqw9vzVFhx$Wf${6q)k!Z| zvqvRU)h)s})($BZ(EXodRO=js@kP<JDLfk28lRgAH6KJ#Jp_j0Z3`f&@Du~nsq!Ll zkSp|Q_-f{HC?o|YBW`HmdFN5?w2#JZ^yevl3yut>v7~5%H~_5H($}2RC4F7^d;%u0 zJz|UE<XruADpqdNdD3wxM+#i<ouQ06jjO%+PmIxha|}kolmB-R&Ge2Or-l_lL;()Z z;=~78T7Z);%eZQ95HacU1%5v5NBQuU1_ch9dA1vmh=Qwguy@dT9q>6t7$JXh`^paF zR1XfLn?a7Vi&cOZ*Fa?E%nOt~wiGdf1M7DL!1wsI;dYW&`=dg7y!66@WTFDQ!Ho0V zEo-SV*3Z{wS|S)Z1T)MDe3*;P3>f(z?bOn!RO$e6oetAL7(XMQ5(e1-tB9Z@>Aeen zS?fZ_AGfW|&Dd>l6{lTbFuu2eJK%{a{Pb-6{Ja|b_udP&_KUvi;4=e&R2=QYZY=^F zbHD!qS>Shn@jGF|jS$SROW8;jr3H$9o}T`vVhsRxwE!P0HsUEU>8wp3PQ2YWrPUZN zqBSMf(;equG`Gnef2BCDe9G_QnBOJx7}jsh6VhVaxMV`@J$DinYyG?1(m=nE{5nQ| z&5?YoaOyQlJd4t)Z#5NHv|3rovy#CUTFK^U9SqhW%%tMj3*usi`%ElFzX+ei{fe>m ztD>#7QN3VuuO3Qc)P`AaDwv5rR*m{f%}pPcD~muymOla>(_!K=G=;0&n~K71s87`0 z5ss6|nT?Gtip>+8E-yX*D_85;H!gj-ud#9n%Ta1;9?@fTBR52j%~6_SyZBM|10P>> zc-ARYm%2B^d2&zSa?v*<+%Gfi2V`h{9Ew8SN_Znixkf6i!~AZB>laH}Ik$|9qt7nb zksS=Ju?B59`03gB<-2b~k4}7&qHYUZzh~<CC=D2S`-k~JSkC}0sU{`VamV$}qY&FH zWFG9tK9F5RspOxBQsy2@CS;vJRdf$kFVnhZZp+l%wctjz=^9Ux+T`UR7ld0IvT%dd zR*ji%8f$Z={iw>WAE+gspec!q^2-S8i?Yiy2R<#SrcSS~FVxSqJs@W;vW~L@f$pFw z=vBb;hLUPZR>3%P=`4m_{tJviQy-@lHrh;V-Mi;efHV;fZ)sn_;Np7;x#`(M5?g{f zx7$<R$MsDXUDz(?Ct+27cdH#NaB?K))}tqSdNK{4wvMb0E@!XBqOY@%<~NYMlsDrc z7K74p+fcddjub+EPQ;;V({{j38eD)E?RHRQ)RvlVAw-eR&O;2>y^`{uv6dRzpWG4M z4s1;o(nwp+D*DCmSz(YV#pN&cP~R>)mu0m{@#a+GZpx_!NW8xbK_<u;8tA7k>(^V0 z=Mg?PUXoHmvI?#j8Ln%e%gugJ8yy(UD?sUPfjFowmKhHw_{c=yr!|%<D<MwF`G2bL z>>vh$D>3iNy1HwDQ?cznyA-Lnrgzlhl%SPA&J_LL>=_HqBW#wmHWPCmWMm5?b#Hqj zP0d?47m%u!o4r_?t}(U27;pHI8h2;CR5Wvcbn}G3YL<l(VT~v@*Lk~o{;KJ(NUMOp zm1fkIW6q*Z)kA^^e!9(jyc~Luf>Cra#%NkoSJ(h8F#QH39TVn^8?H>>QQWZQeL!9f z?@<?s*T9zJke_5Z?r)gZ#PYn@4zgI^stz)Y^tE?PVy(QT5@>Aj)5QN%;0?c$m{0^; z$lQ4@QI=ss-bwPMWxRj5wAwPao*>V(at}K&?LnV<1dYYJ?P#0)Z)~ym@-0jKnu>IA zF*If527JArr_vQ8nK*v~O$~)3A8nSHJI&^%?|UxdY^+u8)kAH49m3sM1hFXl!h_I% zWa&&b3sysVSm3Qpf-a4fmewe*|9&eosUGgGiYPS+{Kh*+jki^Sm?o!3P8)a<ce2>} z`X<fcq43s%6%m+JyZsN+1i>|ALNQowMGm7WXKeStTB@kqS~c~yc!h(prQ)S+E|uO$ zUDd#DcEEJJ=2B%TIn+|))EFw*G`z^xAOwGxMEbIbm*@{@^0S^=wYChJ2%amg40)y~ z6pG~3+5w6C_JJq9qoG0nWGRE?n8JMd{!u$HYPX=w21BJv{W(Rv%&35c4eizf{^H-# zrBXG4H3JFN)^RM+pu|WYeb*z%Wb{!>o#Bxc@?KnQJD>O!3EG|Z^!GUaZxd$jgw!_< zHRS%jm5_0rr_7q{B6cRjU3pq^#M=XrR*kZ11{-F<g-AVAVw$dZd(P3R)&>%KWcxK3 z92&j@g)c+^u%Nrx#|;hvkHyU{nZEZh*Yg)6XbT)P$EK82S>2Qr@7V7nmrXe^U6&i> z09KW}@;>W63K8Md=d-{Dev4cdPq)>2DnyxmXA5wn66e;7&yLpM^$lyZlK1L0I7<aL znhf*%hXN!1^wb^_RI_Y)?Br1}ng|fb14@zHJm+3r>D^S>n23peA4d}Ie|^pTH8la7 zR#_^C=)zas-^@kbRXy7j0Lkmb!Cz%w^D(_k5r4Rml(g=VRRbF;po*<*f=F`_M^9~3 zr*}s}ek58?n5qrY^3&LpUgDBa1_GXi<XOL+TWV96k>z>ItDO#wZb*{ue#-|fHpayz z0Vc1~rY2&Rv#n(xXkRP7Q;oVSWxs7HLds3_pBn77yL#4NJEewfJNcwC$rN^RJSpyz zxdAS_Yq&s3=6ww_kVKDvz9{Nv*~)QwN5ZGEUFmX=S0CDVNAqlK<7L)TIE=6_6N(d@ z($V$Z0n28Y6Y<zNGZFiS^rW(Y$(IQ;Fr#S^Uwa8;@gF16!}q($VqGTKD$ah9)YM}8 zOBW17vNF3#Z7>Z}$0#iY+LX)N>6hz-@^!9%-l?2uAx<ZhU0%i|0OTSiv-cZz2ALka zpMa`&c(+gD0z~;Ok78e;+WMD6PN%+^la?3=M-@!Oq~(oEAApRb$*O~-I5R8#kf5lo z>k0Uv0S@9(BK`yBc}H~=6L3ft^y<HpWv1EXxK?E32|g&NvdUU%n|RY$OF$XJohBP< z6jK?{zC1xSTOlqcw6);iMvA5v9*8Ijc3-QOdw+jU+U(Kr1r>J}ay)g*eLJ{)%Xml{ zsBHy(68P3|uXG{G;nglr!?8l{s+6h34xLhK0ng3=k1SWY_uZw5&+W1@HC=qO{z$|2 zu{Oa<bTcwngtzWZ?GQg5P3)_b!f3*Izin7-gX;h~Np>pq?#mEHwrvc+^hLBy3b#%q z1~tl6m*dug1Ex4jvUpA+k|6o-B2eG-R8y@5gZ1891pCHvGXqYOPp*0`yc7um_Krp7 zwGvmJ+TJ1iEgIt@jf0*k34S|vlk6`RH7Zg4uuVG^4Fv|MEYE8GhLP4IPdR~17NA!A zAN>R<*8nb?gb2~2u#wY@0zRGi{;%D^?3V4)ely~>pbP41{CrT`+xo}^sz-=yK6)az zJ}HjB4ISkuot0ThF3;n)D3~$5qdnRTZ!jc<Fj?-_yGB&oy2>GD<5a#{1EtG;{P-gi zPaz$zTZJEX_<GXo*HE3b>3<Q?Ayuzrb8ly#paiKxVB8(&nJf`fVc;tZQ~VnL;!spm zWYtRI9G{eem4``VM#{2EJHKg7po^0Ht7C#~xRQw~%C3Cl;`iNXcebBxEMaRBW~^o4 zA^83Mh2g%Ix&6wF61Kz^H>%{JK2!egp|w?gj)95k?GeZ;j=JZX*7q7U@ZsfeL!2t{ zHcDWsb;IX{twm0mvM}M`nr8M4-m52Q39`xkf+xjTG2624zlu5VbB~VdbYw$xhd)}m zC(ilXl`6RqC|U5z5Iwdvl#{9<=1Q3F>i<F1p?D<IE>3(Sua`Q(>AS9)vx%riu%dED z2m8-sf4aW4{DnCLX3)V37Z~mHj9r=XaxMtG!Q=;~a_RKn^_m*OdPABep$(%Tz~S>E zy46WZ;?Jt6pv^#?Ega%g4PCgQO~8U$F)$tVxEf61DZm>n{d(Hd$MqUk6o-e0LB-H! zzG95af969N6)#?svMV@ii_Q5Oh0Z92tvX`EuS0y8P}<JM#?pl}*k5Z2%ls{(xUTa` zppu_9tFY7q7FIL2K$+6NBsf;F`-g$S<#qKzIvW6h>URM1V}nPp*GYb0Sb&y0QO@=M zD`lS70z=tbEdXtc)-8bFMulEEei+n@y^@eoaa5QJVqvq8$r9tVsUc5XCU$SmeR(uz z#!HFq$!W^`45p3mSWKnvyBq_C2_P(7%)ydQe>-KNBhf@|(3=+0e)Me|FJeEO9z;?R zg2L6L#ZTIPk9)PeY~9eiG`(fK5yD+6z;%xw7uzGU{zTD^Au$`_i>UbRC%*1Lv9<V= zo*^G&TlmMjV&s0nC*d8Kt>|4j#G)Sg&EW;S17SL;GHCMjlf#U9Hc<Y|zsC>GHK)Rz zY&M9x;s|#gY*~DGVymWPoLk6b(BuZ;#hQe45ni~i26ZirbGIBPZ8L23JFb_e2TRa0 zIJ)qQnUZJBef;*&;=6gLnvU*%(Yeh8-APbw06uN3_>;)tPoQXsQJmLsoLl}HQL$s6 z3D<M}v4t0Nz5b_i_^13>DN^4WPj<AQ-mU~n58nq>E!)iHm+4V6P<w^dv&5o^0%7Zy zFn{GsMHSY1v#rVJsY9_AW#kq_bWX`(H$Fxc8puQtlVXGRYmm)%{5jp*SIAqWy8guO znMs&kVVej}{T?qW??MyVNIlr5gskV>uFfv9ZGPSm-aee;9R~S!;iOfOqTsG33Csxw zX7#7Q3Z#O4hIwbsnlJG9|1F(>Hw6b(GXoN>y$+?t-62epyEW2(6AtYn*jj?hgwKw~ zNV-t6gLR)j+E#3n-&YD;kTxn5W{Yb|AMudr0HomFnb!<!NONB)_7MG{!hS79?r@Z3 zYKcMxwZ+!UMn-4uBveKHiu?8TIAY;v^-e|_1JKZ#x-vG>Y>h;_rcrZkTLR%pZ2E|d z<B2yFIBj-rN7|}Vp0p2_-v?#jal7LyN38EvG4u@i8GM5va=~;xXEE0w7Os4zg;@Mj z%gMg)G}5S9%Xm;G?9nbE4JfXZ=!la$MKpqaggnTfF{Q9yzoYiIczn)D0s&?m5_gBz zBEIJb%htySF`@*kyPk6O;eC~6QyfPq#CiHO0@l+r5j2rQ)soMz^1PbH%8t#`Zfx#z zJG=7HtNqu1NI5W`q%{R^tro`)nLudXm0Q*@fu&Q$g{CrN%<ciI(p24ND@R*Zbp1-$ z>RwSoe(s?sox1e#RObIslk7?tccnOBQ^CJW7d42WqD)1S3wVs%6>EicQNjE*sLq%_ z=NGZeGTIoO(@qpXW>K&&0Ah(F#X%-E8fW#^CZuQOgLDa*dif8He`Z$@H1ivehtG$K zHF7PT^DNU!5tY{Fi?+Lz{+?~T7h)qLIv#VOIml0WZ7hwiIyo?`gRywhl)<DexWQQJ z4^ACi{JE&dXS5*o+JC5pdjAIC-rm)4)8F_ZHjTXee%x>QsA%NA%zIlLULB0(<JEvv ze>0Ue8r;=j=uELVq*E$vo=q_+wdu$RSy13zS&SZ(%)0Xa(aR=TGkxlVEJNTQ!2LSS z;n_6EB-=tnLd*PbYqx>^_IA9!vz|hO4DzT-^qCoajWg3lZ0a4a_VzHkS7Djya`(3$ zy1LYlvE3J3Ghu+J?wRGec}%icra)>KUVXMLcYuR+y6Nj;uy&7$2kQa}g!jUIN5Gk` z_5+KY!L;-jyom$WQweXaEmcGfJGKWBIIE&R2(GAA|Kt#w?^sr>e6;V}?qa)WO#^e< zOZ^|5Nysh6?89)Tj)x5r>yR4|$7$dB8<w6yI-{zr-4|FC728_5h7cEMzi@tKbn!;e z=4=ua_<PUPO&UYp%gwd)kIYqo8H{r^d>L}U=q6Cx4FHG#O*0;gr%|FbLX?4vSh}`^ z!6H@(<Kv)=mPjNP?O_7`p#Dkj@48%=(a!aO4e=66^qq{UJpC>y+M=iksBnM<YzN(k zII9jjsxRvXo%m}gVb*W_Yk#W5@W1qo5b6E?t*u98{Dgt%d;Ww5lVkeW6N@JdB21&s z*Cy=3Yrw^HBrz0J2|1K>)lcO0&Yhm3RIG$sY#H<5?#VsQQK>J7l48=3pyW@BJ5BYk z8y>m1Qmwf*C}x}Oyw2yP-PS~w5d2lV3JSbWYYIl+D@1PW10eKVELi7J4v5(}O6Y`~ zSILKxx(<*1)piB<GykI<cO<^oVk~AH&ksR-!Rw^BqXNH=1DrU<00FCogQF|@r;wLQ zFjq6S&XQCpJ(iz&0MikrTX?GYUtLbcj{NJgf-GeN>y<fB*hTEXu=`+9s1v^p@t|zx zDN(dlopUs(;i=rDdUMDGVneo59u-nK#RL2Uzzh=dS4919*vbH$|ApT$1faLd|Bq_t z@Ep6bBuG@Qk8E#1p{}-S)%*1ajwK?loz@=`P017YMD%-o+vu6`H9KaYJSF}5!fJqS zA?#QIW$&iSsDSXMX{)U$$Ff~w<;jU&nS?t-@zN-`za7t9U!O!h0c}Q~m<yahZ3)+- z+Onw@NRNxF`EV*m%Z9w#pUZ~OeyW5G6rIwVT5!>^Dd<t*H>++xd(MQ%#!@?|$3TTr zk+S@LMK$jf3>+rR3Iu<pSbZfp{2*WPK^&T_m)UTT)RuY(=ky`2LS4wyM8)5b-$o_) zSPHjmfzh#1sQ~>r&f6knqc`&4`L)(6dry=XUuaV5OE2~R<+CBte7GP{ymv7}c+|q+ ze!R@_6uCoq6+!+tHdr6kE;B^H+!(gFM7-YCGdW6zyPsevHXHhJYkP;Tnd1TnbQ1+1 ztlL<)PPy!2&fN=ew=Km8{@?N_BzE}BQJHT2#ERxqs(G83tFkKN|5lR(M)*X5Fh{c% zF4(2F;&%(<tK2Gl`LGTM)1=|5udU2$pt%3la*&FJP_A_XbZ06bS<>2m4*d(vW`q4P zy9w=sPTIQo`IcZaQqKZ+FD+enJ17}mDWpjdv6K5I<$cLa)U3P5I-dQ$_OouSjBpDf zNp*>r{<l;)?kh~43FxTHKpw9N=MzR|Q+9SjR0O(wtAzmmzYQpV)lW;-PoGUip@u4x zM9M1)(*qU$%BVTnb`@^)(jdJlL?df_$2u#=e`DPqTXl1<7Ugg45dbw@pjd5f87w@i zKLM0%cX5?2T%Ab;p;50zm!u{T4aN|r`@xVD$dui_fo}u${8M<OcTb^^+l)S#f~9}0 zJp#3nbRxjJ?x*tHW@#QA3kVoL3BqY>qiQJFd;@;IP4B8m(_5p0#+&9zFY544oTMK} z|DL}6H`Uaj279C%Y_gkbjb(PHfMm9CV#Us6t7J7VJt@vkF4gM%od>h46L)eGvmRFm z83lGaH-UE$_Gudwd8Wy%Zv~%tPJv^YS02>CzmY6f<gj@6E?m6XLbCy8%4T}2#7LVO zAfp+fS&Nm^zr=<9i32mUpzVUqJGBJcUxd0C+k7<o!{r3NGGhbL#5Z3j8eV(R93l(} zq}082o11ObhaphWADMeu*oY7B<y|?sG8bb@5E<uWiJPDQ^|GDTUS`b$7HR+uey}>5 zc_rY-`un@7VlCr7ke1xiLQ}0dgIdJaiK#AbFj=?9Z%6cbeG>6!^<fdMF^4$2F&+e` zsRd47IJXhK)kb%!^c&MC%9x*{wqA}%6_>C1<LK>!wPOCH*WGwj)Yavll&5$X*u(R| zWl+&Ri<q;eGnhy$KF2P4Sz=gb4eTQb4GGzuunw?Vb~;m7T+nIXicZ)0W!+~Yc2NiB zvAkowNwJ0*iVu)=!|7Yz<OZ1WYNP`gb%HtpP{Rddq0ja-m<U35I1I@nYTsfkjbp6_ z<Da};$07s~zpBI@{R!XpG|}%>W#S)@Cr#Yh3z>q~RDGJ;Qn?hdz8T_PH3$ZWn3|fu zhI4<|rt%SC!BEl}sYb0*46v;E+Be%;-j}B}#*BEUb15E^Ua1~jagkZm82kPO#saHP z>q+Phu(kFd4HNbq@15M%DNQ~(eK}hf(H(>16Mscn>pS>apn>!JKQS#6%gj4^R~TKy zt*>si!WJfBk#yQjmB5Oc>$XQGTH3Z9lpMTE0%b$d(HunHe>{)=Zu^2gaRaZ7MsM>6 zYWDAjwcr~_bEZeO{AEm)llrH_4x2Ht(ibVc^cgS>`mQ)RLo~=TKm<vsqfeW-Zs<=1 z`C1@v88oj4yYwLw#%M~dl?eLJz6J2urL**6StCOp1vZ?4`$J&QCD2*ujzjHM+&Jl# z?8kAcq2SRoDWK>Btd}){2Lij@DB#lD?OXhB?D&;zZ6hg#pEWE)q%XghM9}2?ABZ+j zh$HGDd2lcPlDuP(OtBY^CAv2V5#iJ*FdU-aaTLAHqZ3YVRQpbCE!S|fJ@I@bw_M|n z=d$;J*PTb=U%Tf+3kNsizX?rln`hgW<T?Da<Sr6_EDritPrS%`0(O;vmEjh~$}?Dk zXx+r>dfl|tw)7O0O2!qjXt8!xanJ5_vu65@DIa|5Jp-X@YbZCz4WEWbtY66ONqOTB z*7C@)B(vABlDzbQr@mq@&wqg_y?;edH>5pPrt4CAmxA#+(I>n8&tGy8Imd~=bNNP0 z0nD)0!fw&~y){>&*`X0i@(EVQ8ZA%Re->fRf2sZhvS2uI(NW=`0KCF3u42;Jt|iyR zqrb){q~t@a99(X)Jv<MQK}<AFm<`lcophZEIunXD;|T?8)ZkQsNZO2W?Uu8ngbRtW zW=LnZ@*VvXrx4$k)sWc$nT4(inAOt}!}2ZYg$s(jC1}_lw1c(;*w=UMJG2brKe5ql zW>MDkR|Ft7esXwhdSzr~J8A4r^of=9L8@~*{d}|xh&VC|P!WC=eQ)GkD)Ey+j2_aI z+tm%@HGvQ?{w=?7qR2a93!O(Xx#Io{jn<Vz#)4^Ak-=A5l3yw|`QN~4rf6m55OdaH zyY)lhh=A5tGbXDdD2wUwTvZuruJwc=zy8Xb{3E9Zq*vmYYa@62au^z}k&i>9g1CuT z>PkI*T4$0D0$~{`$!_pP`ec+J=3oMCn*KV#48(|sj*r-YBg^;uUC5CbOr6?JoqXUl zteqf9FY5zg*FZ)*V=6a@F&FhWadR1EupB<Hd{&E%&6#ZqU6ELvw$m|L6vNNT1S7cM zR~9AdV<W*;Frw=|rgl$K{ro>g{!*=*YVVz1Iu3mUi}wJa1J1_fE)^*x_6<wqx^M24 znkQ);zvO8C?SUnrAP&$t2xcF|Ec7B-94R@D9ZpO}9uUpc@~QDYIt<=l#DKj%GkrnR zDVHk*!HPcZpNjrh;l7|-$@FSI;C94Ob~eeb*;4Z>SpUBNbxHl6GWaBBD-Hy1t=RSB z@xS-LcDu9w6{7y5FP71ws#?SdsdlUOR`S~nMgWc-aG!n!aN}JCwKnCiC*)Ofa?Dj# z{rv1lUy1Ak+m3LeQdc}A{2J|dnhjFwI4xUouUi|AHY$M2$uY`NLOgC3pXWCL2{8W^ zS(yZx!?Jvx&8i^H7_Sz8o~qZsIyGn+V8xF^&(@=!&LMk#6q$>j9O{2N+EY3vrzwK< zON_Fuud)k0uV~df*3(+>u<R*GJJD>xo?-?u9q+G)DddARAq<HCMnbI-;xFSg1NR-t zy!zB3?qF`4QNu>%M6NBt`vOP{wV!Z5kI@y_rxzb@mWumw>U%vhzlIp007ny_)L-;+ zQ^_yQ&r}XMme|pvNSXlsHtrXp><##X0lQiNGpuHE=v*x7JGEJCTs!2B#B-9t!+UCW zg{wuD0{Wx4zzk$Ms->IP!~$9!rI#5Wtshi35HNTP$^Ex14gxAtD(oKD#P1BAPZSb0 zW_jwVp-x{?{~wG2F+tTogzxDyZ-2z)_R1;(h9~gGMv!U&ML0!z=Xdpp=e@<2hwo2* zguESf2TPGF)Sa5~A|+STZHoPl9$4hPpP&qEptkxlm=GoJ%6fSlE8A{)oFr1c<+{os z7}nN#?;eTN<mP_6iA;{0KUxUgJvefUZ|3K`dcK*S_h5ZnaBjA0(s)6{Uti;h{$N!X z?nGl$)vp=@bRuSP)9_Cxy-EqxD$6m|(&B~L##VbY#h?4Lj$=hHIV*h&Y!~U!dkxB8 zi5}Vr3$D<?W--HWWlybSVquf5@xKjS3O@InVXHRUgD2lAbPEZ>3zEYI0(5GS>%8CT z_3I&mPT&Cf>ypy(Th^gIubjIQoY#}UH9hm}AaGm+pHd^2{57fmfSeF9dG_+f<?d=B zIZ9XCnp(2l<7COa=#GM9X)|N1_i4EuU_*oVs5m#-sH`NQW#d7}*oV>T`ONaqJXNd3 zZ!ZLGC(zQsddx!vswKSfQm9>|&_Mbl(6*IEPXc^12zJwV0k=bZH%z@PB4R9uFWPus zpKR(*am_*hWa#5LJZ8i`T(vp7Y;XbEzWDIZ^c~mjH~fk^#C!B;gxJgvQ1!p=T`onR zT9&H1<yjM`Uz6vjPMEz_n75qd+6qx#fer3-NI3OLKRRzx^C`GyO4kB19+%}m+~(*1 zhg(Rnti--y>S%sxjnab%RjDAEF<g+_W{>{hEb3Xk-*R=i6q<-ADwTGy=BIS~we+9& zZ8_nxSv+BvAA-o%X|e4Hkeix~kFAP0A95b7JEP`rWFV^@Kom?nw0MYRNLSuMJ#Q{E z^BZ!j1|HJ5w5eJh@(kGis>+}vvtTV`#vEO`4hA-Ao;pSohiFR5DSOCWUH5Ro!w~g{ z_wZe&)}vegGT^h8^MY-aQdjm+ciW{&C4xu7M9rA?{zn)AiqJJ?{x!1!p7aIA=>4t9 z9bx*3fW6MI3C~2gx_{!v=?|HI&tM)WOvF&c>sG83_r3E!>wCx9QgSg+8xcehf&E}H zC5RLE!N(3U|I^Dg+e^=@-6Bx%o+&Re{H14%->stzR<PIC=4{)H(rgRQ^k(UfcK@Rd ze|#=q>~cDoIsmr<7~AO)=e-;-0qBGvo)3QTR~3XDuW~?1niF-5=ib{ZT_zc1Tm9)o zhoSh)!zOjO{-k4@>%SM+utHety<|x{8mN}y6r21{SvU}82oj_6FKu#5Bya7hO4+Jl zob)lMl4=oECEq72FX+Ce)|ie<>!)w{z7^fup~gWE+&(W2Jxz1-Z$lKF2Y=h3q<4+s zwdet8|7Dj8-f}$XfF1+H#O+OYwM~RBNkyC%)L0=)u)0up1a(=xkX#zRyc#gdbz8eD z2etPkov4iz>H+|s`!jUCy?BbVYEtn~u8H@%?*0Q~+ApUqoI)Z3Jx-xUK$#e5tM&3g z*ztIoKY~SnG|z4!23&$%urXroM6r7gE*tn2=O0buvawYHQr(<_Sl3RBQO07fEy6xG zQ9$L$mipSFbk$ueN3L@_jf;2F^|X^?FD*F45yNp)=VOnson(K0MbP2$J<07bce7(3 z3qVmK$P&OHZKU&8iA#3QOq;YmG((&dX8%;88MZGHec*gm^eO$Sw`Dg!TMq`>t+T`j z-YC637H_|~rX#kcZ=A<&u*fZW1{|f9FpC`dwc2TAHvHZ1iRV%sOSvf6ndJ!fQ?`I| zFiS`immmFVep>s%Xgn*QRs_+ef4*<X$jyO!Vz%_p;C8!t_b-t04n!LIcKHlFWCb_3 zs|?}*zR+hN=+U>@gP@P0Z(*EryF33c4z!9J+6R0A`&B{h3u$`%NBITFokQ<;D7P#d z#T9RFn;k!Wtm1C->LAJcq)%y!p~$>!f41Ght*5Kp_Jhr*{3EZ@9W=}ie1Md!#hv9r z5_vnsb-lP$xwGr=dY1H76TzYG(K;{mdL!^_vt#ksmw7gHjj}aN2|P_BMI<cjp*?O} zFrzB0D1XJwF2&FK`|5j5Wsj<N!GqgHzxcW|BVTw020|?SUtC|Sq!xWkPYNuNEsAMf zB`trRZ4DrI)2}~b2flwkbGP;smuO^fRzgs=ea6#x`_jdBs5$bY=J?`^{?K)$w!~0A z+<U7~`?*Umv!uFtCYP{I6Jo7h0=M4h{kSPazau~soVv1N6O2Re56ecBRVb!9_l}nT z*@L{nT`@tegIj%`;K?^9y#AyONI0(f)MYDL>}^%q%UcxObaTz53he%%uW--?)SFPo z!C#I=t#r2DecN61GE=bBJ{|V_0&>`~Du6!cUQ6u2$h}AKWz?LNRUe`9u~h1flL-eK zb*k<0OGXy^U`=qsnu@hiH2LG?a`>w%(^04qnw#Fm0DNTynePijt7ocKj%o{#1*B){ z+OI@No4)g_hOES|u2(i{Y{Gj7gvh)h1@>LHWx1phs}mY$9j8C^@D{}goh^Bcemt$# z|D1la{r;^LU%n<PrbZq5<Z*J-bHbZ1{}^ntnb{Kjp^;jJiXBfoFxlbvuz)J~h9*V7 zaWoGOG)3*_s^EUuIym!;jc(Bz(iZa}K7kX1a_t+p`aK{HK@!{Y_nvzcWPP<Ol=BeQ z3xqdYPd4^mCYjUEv3w1_sO!$fylvw)*B`o)h2X0PZx|M2j_Ka`(kT8(;TSH%enPFp zwB)SWO}i8)_$>yb&2I!V*JrwWC%erkMJojP$jz)S+g{6^Z`WwwzOmnH|A-bl9Vy?v z1=Wj-vW-94eiPYuIr)Am0|$7(-`NOzS13`T+8=z681>{PYA4sD$q532p`<&y?QOME z04?+54F~#Tx+#F`5d57DD9bftPFs?Ye}Zy`MdFapk%Iefy&rG&6d7)iH|T5D$c*{G zeFZaDZ?}VKiyN62ON|5eXa?mn-vpb&rl(;<@W-BjTBKw`ZMvD%v+OL+Puus0=3Z+Q z9qqdSgL3>>r8d@IuN#1kUuWLGp5&0<7|!x^!LU6Na<b{&&i4ASdgx9(QArVyZYB$k zBw5lb=rVYtc=`1r``JTp{Wqh_1QPQz)vHW<hOHL4dyl;`%$V($NS#;jeqi^`qu~C* zirnbvXt3#^8bW_8<<2Yh>9c}+FXwm|&4P^rVDd2t503m4RCDBm`7sI4HBb8*u+PC^ zt~9pkwFVf<<H6QYH@$qCWv_Z553n{d$KhtOAb}>RgTtAQ{KY1>tBb&CcphS@jSt&= z$Yfkzg=gV}wrowvXGsEgZ|ve99$0ot?=`*gzy$l2V~H_EQgzLC#kZ1fRzG)Z)pFp? zx&fWImEyz1Yll>|4pw-3{V?+2+fP@>l~pSCJ$3q;zIt0N^2r(I=rYIe>HZ1!g{Qlh zb)D_GTpx#==dtQ-85qZZJJYGweX&U4Em6T+K|r*lTaFHwJhnjCYtuEZ_*6|t?zDMU zY`ux{SKez!qwz7-*%e?v{UyE6Y?AlhI85J7ydm5^?{^b=YQLjW;6QkcP?IX>{PT`d zxXqSB<rqS?#8f#_EE;c=l2x7kHWBIFz4CQ%xqI12|98|Q6{Ay)FLX21T1m@$)roH} z8=_iz4-{44teYCG#uf~%W#QI}*@1Q<^N|CO!B!NYqve=JTkGcUMjnpYwY5Y)pI+%0 zv;iA|hiqLfhAX?)W5cg+=u?!xxY6_=@0gn4v;wStv88Bn-?Ys@O#j!P*Izh%UyxK) zvZw7-F32mp;DdKkc20v}C=33)hta^)@k5W>BKTsjya`qn>b6JE5*+l0&y!g*%p40$ z`^tn|6A}gW-$WtsMHNIsf|gjU=~oUfdqk5}AqRQGMdi17_WEAi$ysG3y#4oIKBj%9 z=ckv~twNuktTv_lu%VYs!1=SO`|Q?xZd$S1^EAepNt$~-AU7Y~@_C(50oS?``{-QD zFn+l^|IeAPb2q#Te3EXZl$R(CuFat(I2I*bb7x&Ba>2vE#4oEp_o19auyC!j1>Wg{ zivcIlQFhsQlyOVxOiO71{c0WU0I-tnc^lfBEZZLuLw<vH)o;oWL0Kt({2AJJZwPjm zqwlQY%BTL7456azaQ^tg>PJO-`~&Giw|%XPs#L5$E4!GZ;lZzkO75j+Oh5jPhf)+@ z^HoGCs3n{#ao%b%Npwq~d*qa47_h{OTXnOu!gc!+G2YYMl33E)J(n!@4oiC|7x-m3 zCM+c=3^r%LuD-ahHSwV(=weRUs6ukU?3Ge0P%gFmZj^y9%^4bpyK>HOv}-5L&Z#b- zTgbUhQr+mWm>08IsSDN5X^q^+rFi5;BMTl6M-4PPW(V`e;1^Ct^HhDBY(*b0xo2MA zI{>qgyw^4I?HrEcw4M$dT!dZys<L3t&e>G`4gX8Ky+}&k0_kV%UR6B$u_!&yo$UDR z^=JEeu<x_U>Z~stsJ7=xMd<f@JPOOBKO9=2?AadT+(n3bd*y9Ch-v<od4AXPrh-`# z<bYd%$&Ed9Hk04hi%X|~rJ29XhCy-i+vpJnxcz@aN&fFi($}K?g`S-ioAa6q_Z`mP zuK1Q@3R>Jj7~2)H%dmBKef$k`hr2$wy|WU(Dq|Fvk4JzVdks6iRp298_AU5S4HIWk zhQz1>;{U_kdxkZ+cH6?SEv&c%0Rce;5v3}<W1~q^si6cFLZm3YgwS4b*=R=TQdA^# zf`ot&nuQjc0s#U9P@0s4o&W)I?%*o#x4(V%zV?rEUHkbJF?rfu=A2`UIVS^EW;L;3 z={LOWm+Y6|?209GB@j5Ijce_nKgs1CYH!H{MqzRr^7rrh`5-K5dOpM#+bAzF`en&= zj--z(eNGY-%3GRAd?f9VSgz%SRP@G5=;;v!&y{Ek+U8Z5D(a|vCu_md6+)oc8ej(N zB)3ypGLxol!<I9&w3+IW^8PIe<tO7bS4R^{T1hHG#2pc~ROdg)m!6Op%`@S$A_3>4 z_M}U9bVnaCv(1xr9uV)lwy;>r!R74sEr4$?1X2KEK~Qgv(wA6yKb0BQ*))~#Ua%aE zI^8C}r^s2E(0fJHSQS-`%}~3!uxJu_VP-m<*d0l3x-!BU?mCuR&5OTHfK|0p{h4cP zWCEb3^lr09e@M6S{1v723-_a<xZTb3q8kh!4FwhAd;M4Lpn-iEpwdBFYW0Dgpadb? zF3viam6vMHX{FzIXX;-VI^g=4`3yE(Kd7=FZBO(=3Crg3K+W;De$Xsd`FK3)gWf;; z$4(W?8{YJGv4rmd^N^L9Y~!st5Xh>o3(}ZfMerl05^jO9<$ua;C#lU<VWj=aDn;rh z+B>nd6`HEAZk5P5*VU@q?t0{@UC-P1@Ef$Mi>f^!*K8BiB&wOQhS&kH+-hQWvNISs z?ZC^)zCfa|Xh@;QE%gJ*mE<48VXV!i$=F@{|1o+14Ok{-l!PiR^?-ch1}1pCqR;bu ziO#!^fsZ4D%Pdd$KTiI>lfWDH4kdPqhnZ*=DwM!;G+lgdq~<m&QdT4~A}Z}+@G*RP zOQj`}7$WK-a8Ko7N3=fks_QpCRj%w5lwOO~4E|>YK6>(t3B2^|A_ieU+L|0hv5!=k z8Oc^ZhNN5XZrQelk)<1*RYV2ob5|s$%sjGuy&N&xMR{VDpc)z?ytB~8_~ke(;e1VR zcX{jig^IJHyC9A1k!;W0xRk!hiS@5(^-sJ?&zq=8qb^SWbf&yLW;UM7EA;~N%_?cD zV)-n`0D|6nP&XzuIe)MJS;Rogr)7Kx4M8!7Q6Fd`?;F)8_viO_Pw~SvCkGnyZPKS7 z|A0q_<s`%&E;X{h_hWn?4BaD#!awCmmROoyK@N%y<&E=QB9wldV-!3LK?@$*1F1?9 z3x|xPRjmfBL=yOh&tlzm$6mhqG2UF6KI%d&>L69y$C?&j>dEV^=%}Q`BUTTzuW@F( ztm#Udd|i}1t2>{B*<{XG-u8ET&n!^CtiB6!4){lP13y<6PE?51&XsNQc+kTLL#&$t zy{$1JH}g{k9S?uwMND8~{LfU$Vae4GHeVR}oCs(>b0BuE;R?XjO)pxe^Tg&Rc=XW* zTvd$bSaIGmVZ(lkN#9U9zd_Q0(+U~-?9aWh9$JK55v|3-OgU|iUwx+mH*TpGae4H% zaJ@a+mGSd;YoWK5R_ey5O)^%Ki!Bp-yeb=bjn#y?Js9LEb?ygm)C7VFj=nz<G7bqp zt)i4$49ELRf1L5b1likXxkncD<%2lVpFLhfpP^wk4AM;UrAXuKP%JE6H^bQxnW3X; z9BI_1b-&|UOe>VrpH=9+`U7!!__lPw6wD}76ic>$B(CK(&NUY4eRyJpc)<Q0Z+`bO zQMz`n*AiT-eo(Y`vcYe3g(0E2bZGHMhb-iGfJ8y&O_Zh?$&10T@&W0ZoO;5Tq726C z`C<XjJJDYT@UApVjzeQcZMQnehWM&sS2!N)6V5rbC<OJeY7dAy2+?56(><?}ztm-+ zjE&Dnjm7(0>`vT!Y|_e-ag8;bV^yq?Kc;vTf7Zt%E_-$yS)<`)IBD;nDhP)e#<p9t zE#H7@sP;z*ggss(RvLc0;ftZRu}4r39NCtjs)&kFq}!-{3#13OC1eY+mZfWdwz|6o zM<`rYBx<~J&c(Z`(YPvH{p^%^L-wZ^=!mx4pm&5ze^8G#^ofv|uMw~hZT#kyOfBk_ zTncJjtZJp<RRUYoXA;yx_i;$qW(e7Ctx|n9xOP^(*gEk)H;C(qIpBtQ`jPVrNIEuM z(YX8%mKmX{_gfcTvvX+{3E2YgDjf;?sd+jHSo?+MjL4E#*D7c)2$3ccBuxo*RMAdI zofmssxn&BU3sW>+p9B$gKvj&;0;&DSf}i8a_l3$MZ{GLLUoB@!R5#1cya){m*odj7 zlDc%~fKSeW0Q(QbALmPB{rskWqT?)=QeU!QDj(~2+3z2$))5sKLL`ODg45!QTl3K< z3nb&ppMf>g+^keIaoxMa)ut`zY`^DV-&w%3xHoPa6P;p4?Esa*CF5A`jy&*51+8sp zCZu$Bbh#~3R!=bx*N$+soUu4$+xBDO4qYj-v<^3JAevaAN0i^)FWz~LQlXruZIOPe z!WK@E2b1gp8{6>YfltmlqWV>t!H*Z8ZB~VdilBGK`E)X$X$}~|bWI)~%47H&RVPJj zNTs@+h)p#ai=EBFg7nXb^WfKYZ?X>L9e?BCH@xWEDuy+=>`*>tXvo8_^i!s}az|q^ zhw3JHhetrL3c00>Gh7>H$sawiA~hWyZFDg9U9v<+r%H$Q`bNa0F}(MzZiPzd8Uim8 zna69SflsN;S_7H$nqVh^6leS1_oE-}Y2u<sdh<I3cuYlVSVSr`Jui^whK^;U3!>~y zSg~=Q{!dxD6kK_~sik%I9n!O^kw6`ye7vK^8DNiFLJI6sY%8_{tgfbsVvnFZwQ{n3 zPyQ{!hJ**KY+IOJVDtJ*X!&oTPyz(h)b+cXkZA9=uYa}zZ+2ign+(FB0Ni!7__0{R z)gM=h8U#KF<ahS|1Q{|Se~0;hi4BVp%y)4X#l~YQt;#$+0eX6p?F&MdbJ`JM8w2S} z>6oXjX&EULhfR6up}yv!UO!=SmTa3pY6k>zj%~(^t^GJd$sNK5+)q=pkYB*-<&M1y zyTEYI$&9M9H)dCDVUK0q9hXL5r@{@AC`a!SGzE1Yg!>v;|1ta`xbFk&wbg*>@;nJ7 zfgvFnyRRylVG<uz!oplS{CL;swh1LS!fOUa(W5Twap>|E@Kuv-eHth$40PC=tE+v4 zqgB!L{mk*tfr3X$6yRee9ASj1d32MZPsY8Bm^gqvJOn&3<PjDtTg{SM{FxTk#9Po2 zG>?;+B`c7c(1TVWz@&xPJ{ne5_D$q~K$3pcezQw)cme5+gRy{Upr)p#WOt3wEpwTA zoRz@{a*OpV=1m6XDLk@d;_%f~Jb2Ezmj7V&L505UL);0hx?_)6ycO-vf0Rx>tqSBd zI8BJLSr%(b{|=>S+AD9MU)vdIl!#H@%eI?SD`(=f$O>3FZ?XU!$xHgtycoyS?NsRZ z+?yeYra$d|E9-sQM3E7bfbDVfH&pc2V_p>jJD_5FYHlwDuaDylt&Bh;Vs(l&a4vcE z1pOA-wtS<PdvX&Hu7>!){4kV~7A0B*o;=z+dFpE(NdZcO?;AxKhqN5z&WHqov0XB_ z@netrW7obP3R4g+<Q+e}Sa6=yo=B#>Xo8Uj%W?KFAxeSmQO7(D(gU4Nh4uYi+KIyB zx0tQz$se20@;*EtImg{m(4-nVd9&aZG2gyeydyeS#SCTfN=@@~{$wyS(4xg`^Lkam z!eP?l!oL!7^Np)CK1z1lIAfI-PMX2ftF>YYUu^LkB6ky&RyWh*i)Fnt-#|u|r9fFf zKVW@k2<MbB9{ABH7h;l`OTX>9>ycJTML|}4ZN9@`^{OsXTJu6b@D&VDP8i~KV>ADd zA{sR)_`#tP%j))!9%_-sX9v&r02SjFWmm5U31OEmJZMy)4m*_Z$B9N#5R@bR{1Ey$ z(C_3(hPgU(50^w+pyQ$|{6-^b4*jHaIUs13wKyNBhwj`OMsyb7d(Cqg)0?t>8RymM z28G`Dqr^A<Ge<%uYLu{W-R+#)jRZu!W8S!68M91)vx}*nmD(~KV1LMY8HV05A_R89 z@SH`2)0lGbyIomExNoLC%i<t8$zAyf7JJJLZ|zW>e!NuWiO!@e`Cj?iw(F%9!xcBE z!a_SmeMr^)E+Ss*UpgM*D@$X#6wB^*dil?E@~*c(yp>aPX)uehJMF_bJErzv+#>~K z*&EKUr{=<}tj-O*m84ID%Zq@?e6hBvwXq}-m%6q}bjZeOKgBupN9XoXRXp;ru#ST^ z?rJNjl|_Yh1;G}k)U=C@)3kiwmb-tjH(~TDxOB~D8=*UcZ^Z*Lara%Z-x>UPmn@k7 zo5=1v@hPy1amHr<G@-L72{pDp_~E`g;}6mntKsX)FHht6OR!DVnJG=L-VHoMD2Oau zr)`$|*YR1g)~fE8+Xml=3}|*cep5{!*|WbBZKctLzZO`U5SF|v-B0L2TEv{+UE!jh z#YWYO93E>i1?7^H>bk#$2e8ZN9(yzf{Xo8o3p}i&2wj&~Pn*jyW*wH%J5O+Jbe9$w ze|j}tdaN5}#(hu}xo03dN&^pUqF(ibai|#fO^!}7DpLb4+p#qM)K+b-WOVTCl1-3r z16TWm)<8RT)>3;WZ#=ouH7jF5Cj+CbIa5;Q+>)B2*(iXLPP?mt0{`lY30qHa@O3Uz zthprc2EbXyxNaLop@64$c(o$INUc48MdY5Gv`3?z30o$+Ze7c4nNv}dVNzCt;IKLC z^h9zsFNX&bLAlu|`~CGe1LxRsqBbPP;qtFYqdionjSs>GXLtRB(*Cm%{o0WJw{Z-s zEKntDGZedpBv3lzVyVz|*ScxgR0foot6;W|=oDQ{;!0p9AdTxidP_Up^Ap5o4|H0+ z^8-N(0A`YaojHrCY}bRA&#~Phj`D4Sp`q?dLd&QhJ_ni{LFsYiT?kT?VD7}u#q^E> z*9G$RBiF^cQwo(MUD1c98VY8DEfw9%ylw<6b)UVgVd4-F_U_jBOu?ZOvi-LGMCPfI z-tmlRY0_Z+AIZ^n7>9C=$j+<R_JZ>is{v0y&zyS5!K-I2^Mt=EGDFT-t@V7oU#7kr zk4lpBl=qdX$fmnr`UG$@vRUYsLD6x3S4RyTx?IxKA?4OSwvp%oJ53IVs6jr$^&YCc z5UR3EyTvcCLE3RLFyTyRvY-LC!Sh1(?nF%L<DuSSxS4sEQ&<c%F*(MT$R}_alKhtz z0Ed3ux3MngU1o)U$Tk(-YzGanQvgWt{@Yxpeu?R-ZhSiF!f$y(4{H7~7yrWYT(bnK z(BhL^43zcP4?@@0*E^ZDk>sf{vpE@RzI|yzyL-uq0N4V)P5c$7HwJy{UR~WWec)9> zv15BE0mHtY>?kK7{lT#fEql34`7RbP@pkVK!2vFZQT*8+hPhHp^8}^}tlO9J#<NWV z8Q;Z1xS`Lyy4H0!W42Ji#37#(-;)%5{D_pP9*m;MW;U#QQ5`0Kh-+3J6?EHL4fix6 zS1lTwc3VyODa?f)<~YPD^Y^T`a^82cs69oyDwFAv-Mp=%;o;x<(J9r@Mk@+FLf_%! zV70Zp!!CjUH5<Y1hzAuStQeql@Y0g}N)eW$FQ$V}U2bbPcym0*!0$A6g*!fLHMVx! zx=i=%S8!i5npiG$$0|5`%J!l8FaCpqCnF$r^MH8<%H7S)>VQilBw-duP*Te8_Ly8+ zyr%fc55Nlp#L5Lw{Ay`!4Ou%3ydH+k-b5c}$Li#V3+ZPJ!JZ=_sq3V4HQAX^&Hi%W z3#P+|(rM{iQ_n7HopitF+MJf_;~`<ppDj=!;JI3T%~Z7Aywq3al<mB@<k*N~{e=&E zj<MN*KQVg_$XLPNFOr%;eF#)THioKw0$Het>|6=Mh}g1#w*wi8KN#laq8qLn)9`S! z$$lrAk{>(W_QG#?$5-KM>o{Rpoxxr<-0|yGfths6bn1$4OYQ<WVR~>a7kFGu53?Pj zS@-x{Zd_yEvC^H@NJIIZtw-Kzu8<qNH8<TKg{m7XF1pi%Z1WhrSAW#Oe%;-lqy<7d zapC~vuUr1}kA{$K@9DoJIDcjU*RksT>^ZgZD}G=L8Lf9@&YA@@ER(_JVTQ&jprxVc zyoy9Iqb@5SEXL)_Q}@`aS7+SJZ~HgWFHkO%7v07QIrVBWO);Fd?6_e>1(?1x;t<RK z!KttB2WS^f)dvOBR-rNgOoMa!^J?#GnBidrKX019f@<`|=2Cj8A)GOX?}@9wW<U7k zt$in7>p9WF@bUpJrf&T2)QWyT+$Zy$s!bKS*KLso-wd>uHZ4BXg$`FR5%sRHf_|Fb zOFV|NL6a>DQ>1<PD^jfVkOF=lvs|*@=Lz+ld(lDo*puMQbrC?p$758O))^Rp9+=~? z$wPN3Or5{tXqYKdK3TcStc16GL)+f7-0Cc`U=-@!PZYO)B;_5@EU1(A?0BxrJB{)? z4;>3D6VZZ~1iZ=w|6o(2?QEs5C5?p)ec{cUEucz~^M9dKX72MeQT*n}BoiU3e6fHF zS<gQ{zIX}E&%lXAT@5`x=>Fkn^2D`>IP}0&zL=DmrOtGH0l@c`mT&>*z)5eJ0vL3t zSz?z2srYl)C@;0(1h3zfVQ$GdJU_DVLUwMI+M^3<(_6%#v;m+n2S6f_o(}B+gB>0M zBHJKehK|3K1MXT1eo^f~;3(EMb6Mt@vHWy`ak9gO5%Vz`>I|{EKXRvqPX-13_#aph z&{xF|&L=t_p^6(z-%Y<~lz8Q-LSRCHz~q|rM>%DprDfQLPZ<$CDC+jnl*hY_MzS&Q z-Q)U&zdQ<_pWs?%(ISAK*$OsJ>~YKEohs3Yyk@O?e^T+4dY1Ryu|LT$tF9evfbbXf z`ODH`Z%}F4fn%;P!$xn+k9T1(y8O>|96lE%`X@nmcUuMU3oD;x&sWdTflckvcveIO zE0l9d-pf+r$nxsy>ajVtF$?#R->A=ms=t!pYgk&iojvxF)AN#Z_%`Ee1q8N5?R*fs zf0?fDQPd3qdR!2kz@ThApzn|GvNCOZ&zt4NTHVVykM26RXg6Gw&2824m2rB^)m|jl zH@!`>#Hzwe$)t*Rn_ayQ6!_b){w#|Q($J4sun@)H!uW(KaW2XX(aeSV(J+a_(FSeg z)k_stitU;=qF++`OuCvvT(P;oximKWKkeQLYNO9Fn4p$0U50H7s{r*A{(OLHNw-4? zc9k~-=z&GZg!Gp{=b^*v&o%PO0SPN23FFVcfT%U<`sovU^-l)YZV<?YH$xfQ`ud^< zz$siN7LC16tgvf948kb|>N^wEooz)9Ozh@6nU_%U-b!zdWv<Y&^>yBQ=}#J!6Y%_B zbFnP7V|hl`V=lgv9QqPqRQ|<7J%{)8sSoZqPR}$+AEhj)D!YLiVGvI*8Zaqs)qy!4 zbXw(tX>MhdDV_IfD)S|KWgKDuXIIFNwaSiV9VJVW=@OB*$3r9a_4};qi!Ae$n(924 zhO(5P`HQ)~R3zDxfIWUz!c-Z0GnkZp0?J>D!b%N$W1AB6Q(cAB|9^53($C}HJC_gt z&7^NTYizRxF8<#LJ~nXyV6mvYnKf{m$^em&@mil2)2S@Cx>Fk$XXc^?Fk4uH=Qny2 z!K^+KHLKz$Rc2P!XR{{b`aVXqB=a-x!9S__@c8&@))c{vLZc3Kc&ENzuhg7>KF&3q ze<Kar5in&!Qmb*S?Cqw_(6u-k{mPb9dI(NH3fp*_eV0AmKaD)H?fM;UA4xCmH{pq$ z!<XtY{Rvs|K~?Qa7>~AVdOJH+qMOEH@O@ox9+Z@lo*9jklx!#DycMxAiwe_2ePXar z-vc7Ej)<(dp11^1bl@}q+fll*dwyUp9@fy_<qiA^+uA`lYsZ}^)jY5KHljny4ZmU6 zF@NL(c#}v#V%3fA+$MC2F40F)SEVNp#b0sc-4R5+#S5?vZMV(vFSc};?DI+4O7`=~ zwiT8wLH3ZUiCjfDCz_%U<X?q(=^`tFuRAqty6+Q3H;!5u51u-7Q}=#0Hlf%E%9G2N z55zCPLZcFan)WOk%J7tS3<wi#lbpQcQEIc9xj{|Ad_EO9jWR8`-s3#x?e0wZdwW{| zY3>Bd*48E=06ZO?4ZVab>Z~i|Q`&@DMl@cYDVc7OueUutbfoHj*usZZBYcgdbGP&> zx!OB*xlI&?Q5*_yTI))~sdF(F7Qor??ETf>Io?2~?Q%Zb7_)Yo9mtFoWLow%zsRc2 z`6vy4pqt{K+yX2>%6>UKZ?Jk`CJdhHs$M=CW!q3<eCV+g%9w{>L(oA-DB9a#b8X(W zEJ{h-=C4TWb*C+#du$5UGkDy_07colJ#2Z$KhcDb6X{<Msf*7JYG2*n<(9_#y?2{2 zOgETwwP9NuUQv*3g#dFK;DoS-CBxE&!nC#5l2s(*_m(X#EL<1@zJ{mJquLJ&qIKY1 zKqfJ)$C69G-(r6T5+`8q3r;RRudCtE#?16NAKoXGA<}1pI}3ux%mZC=2;`pLko1r` zXLaxgHJ&RY7h=($4!V`Q5?ayHk(jJy%`IPg!4vIB#YhcXY?IevU79UEn4<So>6&$0 z5Pkpk5SUw|Q5M2R3Z=YycW}958YXnOB0AXrftRy(c8He<{Qg7Z84wOrC2u2R+LY>5 zU5~6`iY6=)ki^2kd5>b=g$^Cjk4dwujUvVxD~D_k4Sg3HK-7Co-y+h>JG!%PP3=%? ze4j%jeYoEWQ^=zpXK889FxmrE3u_M4-2^tV?56+Z%4S^QR-@VhVFR<xwCm0awoP(a z9c?K=R6I1%CC^JORM?|8k0jwF_O#or$2`Bitf6~uLuV4fUt!<1%6_KbRh27k6>pYV zsNqB^ZKc$?f9O?=7UVmpRmTLUh<J(gg8hc9faWUl%c5#!h$7q6^rRovkp)=_7P4@1 z`R7hk_&eGhN(y5mwaFX0RkBt?H9IsEuwRGs>IzF~>V061Mz$(1j%B)6H+?f>veTyY zzy?hEL@j;i?_k-7Z?5=N4P~R2@?F$Im1799(zo-X_+{%}#*p*8NWT?4JNkN)>2tSd zb8V1$TzfG&G_kDXp`Tk&YW~$P--u=aLl=#)jBHTEdC@ThER*Wl>d|qZG{k!IVXL$@ z=|STiKdiP@1k145CUa1dQjW&7O1h0rvL=fY3S)JKSq}}-nM<%3|N7rvw}H3@Yewbl zD`Kv~@7H>)9I_N2a7+4t5Ha)#M$2JuVi)*EJ5T2O8v0ENtI{HWXt=DXL_c#^vr}+m zXr+|W;G*UoIrt)oP;Y`i(vt6~9n8f6`soRGw}>~~c0qJDD(EKTy-FZ6DzQMvf&XJJ zL<rqAk{=c+v|)V^@A16mB--iY9Hu}&WH`Rj0|~JN#PlswA=X+EjmJRVchfw^H&r_2 zuJ-9#5s?ZjQ7K~SjTg5gEbZUJaBpbenVAFjHX+(WA{AJ_GNW-Vjm;LH6_v+4xl^== z-Jj>=T?v-aVJ7+G(CRnDCUi%;q~S3yFk;hluPUwgV82JmPmd4159uNPNFHKE6JPGp z*n0oOT0zLETls4z!+wod`UHR6o|B(|+h|A$8=e%Lx_fu|+&h+8$AhZZwzsb(I9ld` zEp%Txi{G=(l3HZtG`#plvg7lcd>C~wVkJ+QL4NsNNT}*2c8%YmK^DuE&+4ALzZOlz z-KjyvpZ^i!_U)`GlI|bHUp2%Oj(pS*@02@Q-T_#=`X1{njgG5Y-S2<aAl|AOgarrm zt*V!Q{$>-Zvf;-w5)HC>>b5MWxHU`~e{7aZ|KM<2hZWjPfQ^z<9jczrlpH9g+<_AD z-gaUpdNs1`L6liy{+CNK4w<5H*_&i?<wLhLM`q8RTzzEOR?MrC73KcO*!u2b-=1M* z^(%Mk9lh%4(Eia>ye{6Nkv6N4sbE|o24eu}F46gEOFy#E$FHlMF<PntnE{13>eTX< z)*ttK^itQaI4GSEH%l{2Cx-6CGp=!$cbN}Vr1Z)sluf(4DRfE^^S|Yxd!DcwB2RSr z-)ISaIPDd-xVMb(%vm&`+;!{&0=j!t!KMJ+A_1mxJdW0E86BtU4Mca)xCw*kj`o+6 zK9%pk-4V~xaizZs>T*<DseSOsxb_=elNWlMsQp;;3`;mK#9624IW*rnJ7}%4vbWP? zqkY{dapP{|9Xe|t$;S68Y*||4mDJBB>BAS51I)c#2)^-`uk<LEO|7jFs{#W&yvpn* zU({SP9{!QkZj;YDfNywJwzN;nm{7W*QpRYdWxA#+Yi8b6X}jP@QF$Uy`eA&a<96DJ z+#X8mrd<l?CIR%S|0Y~z7w=&o|2IWyfh>yi_S)oU^9QbV-R7wc4GkG)dy*)Ui$GWb zFDbdXAf)acd=pvKLkzePsmcA_0EO3pK;HclSEL%#lkg>izQF;(A+^H;hY_eM3yN}x z{h^!E7b{Tj`h-lMqqd&<nBimQl4y!}X64~Vx8pIrfyWE%ON4pLz=?jbPX)QNx`*i~ z8S48&|K*PRt&fi9*@~d{Sa|s6n3x=XWURNd<kcyRNFpj;%t*bUrPES!aYJa|$0kyh z8nG*fISY%fTDPegbPJ|@%loB}0%y*dMVm6eS|tl<Z_u2LMTaY$Uo)r{7M#ZhU41?$ zPFPdQ1uE>*Z}FEjQN%os`bl`d!=M-AM2|<(ZOqeMDWZr^$HMC6K}V`cwmPQHP_t{n zUV?DF_gNKsB>F&yo=NsgY-iJzd#}fnxpYNhHzz={W<1`vGaNpq^G8OIWZz=KZ@}f) zv+Z&?llX@PsU$=u|1i3k65#0Gd&Vqcx1i!TUbOLd4iK}l$0=OVPdgaz$e*fzyJ3xj zGh}7kIx}pns=oEupWM2UHhpw8qTp&qjA_Bmcka|Jxy5eREe;ouRcXE5s;xjOZAaQl zxz>703v^OQXa=4-5={4g;2&HPtZv+|mujhflc2jnOEHNrKE82QR9S71;FCeJ>dKXO z%^{WAd<-1J+k`%20xM^oXlquX5P;ZrX!R^*9@M(PI-)+l^Xk+NsZo*oH%&BPBNqX* z?AA8Uh!lW8Vw%}g%`UM91-yX^f2BxqZ<os{5G|>iwK4qaY{)Pw{FG6+n30vMwd-Wb z+3U%u(<bj)acoA)3tSyC(iSH~gX?VoFy(!Uv(loC3lP>Ze`5frew$Xj7&{$IZ>*)N z&bg#C0q}ynNdlF!qtj+X>?hIo>z(f90HArkEv1gMm>fymoJA|3o1iIrskbAv7WBt> zd^#Sf5t{}`K>1Qs$G&5!1b-vF9-@P$x2I-CRt1NsUMJA|=)oibpZ4K3Yk&a0!?C!u z)YXe1?unLP&*q9+VkCk93GGn}KPR~7XNxA6YC6W0A4#YJ_x}Y%F%Zx(a~|krKyX`a z_;KJaw%9={s{F_)Lo;0&)O`6X&J$0o6c}Xsl>R;-l4U18-dbftbsZwHLu-%SKdu*W zXwQ5~H#Unt-W(Edvphaj4qpxNxe|Z`^W@x?U|ZIj*gj9=sTCFox@Kl14Mzrc=#Jmi zK*jG)pJe@s^8n>4<ilCFt&0yGS^)81^9v&aHwS44n7P#ipeWdf=Vib?h9fMpUq<CS zYY!2HgVq8I;AL3?$l$ayP4wt@(74|D;Rxjxwg<<@A#3Y+1Ll|_mnr4#XPAkZDf{KW zO^E4CYoUb892$LMyCuDWzA`aE>6m!nBRv~D8Y5*oW*3qvhxLouV`kX`-IO|9t1S?6 zqWnU;x^QHZg+i!KO0~0Y4M$hFZJ2U(!Faw}Q3u+_yu5Wnc+GCv{=FbH+lzS3FI5n7 zku9n3yGl1h{;Z~!t~;u4dty5Fe|lmRpXh30L5l(qR;5J^;9c?ip#~x=DT<^#T;T<h zZRO7mDbaE_0d3mHCZQg+&!Uso3}oN~IV-<Z$B)$l8N@~0h7r=lN6Hy1_^}Ds+nR;H z%eP9gtqFOi1k@^Xky*n*A7@-Gi}hRdybp(}8&UTHJp|W9NHMM^rkCmK5vpjcH#hKs z*~x_=CN1pLm`W-Xu)0^5r@y1WI`9gP)-gFWxmv9~lTf@#hPKSuDz2^(r(v{s+JL^< zM7-kE(&UCsnHFzI@BGcNpFq@zm1e@^%eQ0#+x!mxTIus5Kqx@1jCGixGwG~V-zHz| z?H}n+rP>yBh*j6B8?;igE?M%I{%qIu9^|V>-aKuBe3a<tkfmX$t&Uc(O{`E5{;Km> zvCoTqMD<Y3`U-ud@s9P}lCXgi3Z5_gv1aD`f^AKQ?r;RfYBr`x(s>~UK#bvz>;*-b z`uQp6mv{6q##dL0?Hz?&Ko900;f42~Z7#l)Uu2CXUmx{tA;(dRGQ`DEG6K^-)on4} zC(>!PlA~9Nc0D15i&v{0lY9Sz=kr{3TJY`^At?htZa4#zkFc86`7wNzR3(6#VsM1x z0YDPo+e|Bn-EdEz{&Xyq725v5y*KyBtXmPLwnJL#ccb~>?7AJccmfO^(!!0^IQ+OM z2=8;aCqD>O&wCX8CAQuMF`BbLhUTBnPgK22KR#2$)E!5jS$q?t!_ed=8LW>IJ}2Dk zo4hMMT*&O?BYV-GZ3Zs123(rQ1<z-K<PLVlfMT45ni^wTTAC6zAQD=PnIq-Ffsm#U z&8&I+m+Rw2mGh{yF=QYRSUKhWxY9<|e5Q3~fw)?sOEPAV3(F*AXp=y5#cf|Ee;q@q zVU`7NY#=vDD8li4$MTQ3aTS)wj_@va0px<$YS^%xHrg<aZw|IJmFLrJ2GzTX!YX*F z8{^aRk(!P!AjHrW1-f{FLIIcPKvU>OQdy)8y}>e;`BKlbaH;mjg#NyW$qoO>>4lc# zYww&gp3Hucaj;_81Qq%BAS%c7)Om5e(XP^JA{@3_-e<m02Nt6j6VVw}TC(dswllB1 zZb<*wksZ@sIr$r)l?P}aO6`M)5R8-ds&e(kYB|{<ifyWNO;^AI@1*XReeD@O$0L;s z>)*6zDBrshUMMteb4d2z)Oh~@{Qqn}>|Gxm|EuJu;h|tyH~-Bs3Pk1sc@oYhO>WUW zCu=}-4%1A$Rv$3iv|up)-db{4N1AT*P@GCy1W!^|!A5w(1AtEqYCo(`b`wTtKw>&I z9{G=h<d;~gK?>55NI&zc&}wk$62?aM7gpm&Qf`A&k_-<NJ3eN<O<=?OPry|8nmN09 zm~JIQb@|&#@_O_Xb<|n1<W4{sUSld_ykWTzI;DRR8T+Zbl;MsodFb-k58CgllU^%& z>e!#SbOt3KZROCCh>FIl+wg#Mf8Ye<mt<d1*&;PSe5-G&!gnH&SNzqv6S3T_cXPdc z$9k$FPQj8I?2ks@h5kp-#w^BDs^9GfGS4qIb)Vw~Plqjg9G!px^aCISrblb^o2;t3 zqnfZZm8+VCaGCeTBG!#W1NLe7A}+*#v#G9zKBu=X*EE?iPAtct=R#`C<ULh?cZt{( zxnFz5vUptj5MXd1zMg;q0Wb`6Vc~tix%Sto#kFbEMpU6u_g@|r`B>}Q5mTP~24hrV z@!}g!W~;zPgj0c8{Y8MCIFb>P;ddW^(%k1-RVZ5aLhziz@y;i94XPNO=-N9qu?+=7 zWY6aV@Dke{mIqaMkggM3mju|C{-6>7*)A9!91=pce-`kf-L8GzARF^6pw(CA%AUzL z2=08qmperqilkpV@Ox}ml2XkbW89*G2=K71+$YIR=qiw|<Z4rROJmVST6?_dvpG0z z-4Sd5a6{BGR<UPeVaIJA=;Z3NNs>Q0ADN{&0SXF~w4Sdg8vYwAB^Lfc&24LbCu4X> z1i)_#ZwMV@D?~ZAdvBM_29DJzvos>#?GqR2e&ePm>fp&cehFLwpXKQXcswv3W^?O7 z;ndaO_oAbw?BD&1{X2Px3Z`lBA$~&E$uzf6W?6fsd(iiP%!^6SoEY3D>8Qsb;Ve+n zrD}K%TolFku!TRPKz&Q~epGfdmnk)#`0PmXp&J<Tec)Sx9QUy;KAFOx1J;!y&kygl zeP!c~m>zs}&8#6;x9GRyq1eu@C-OYfLMBbT8_oMwSFODc-rw=tU*h%cv^-VGoeS4u zh3Vw<g<KbAhaSw$INf(MBe$uC#ddT8#XdXOr5w2xlX>B`ws+!1C&qMU5YCAb04ddz z<;{A`=gIXqfV-Uv)n~T;JH^{IxGYO8AQUikYg+^6b^0y?IyP}!;C$iHY%(zl;<MYu zG^FgkovHS#H^U}o(HgH%jS17$d(bMye7_vzKc)5msooy=3+&^+%LS|g;&np@Z6mR> ztb*T+@S+TOd1)(^lJAx0BH*>|?IA8XgI6#|o>W>%u`BbB+0MG+*v|MX8uurF=3EUk zjgiZRvmG}pN8QItG~f#*anRo2cdceTrdQf%T!013?LlGAyOG$iZMYUd%wgg)M~eI# zwUsQH#8G}l5oIMypA2e!x`Yq(U9{R4+!Q^wm!!J-QOO83--0@-=FHFoxs(k~rVYu) zX40Nc*n;QdH}1}^1n09c_*UTh7uQmQ8XgZ*$gzCUf;*iLB+wVJu!$O(5$}=jmV~L> zE~1G{|Jd6Kw1y92pT(gm7YMdq5%uQCyp=ZC?g1x%tinh0dO?)pcGgxgFW9Wq2Z|Uz zv-ZX;yCC^X&a<V|C-Sy!7rX-&Fmlh7y;To|xhOVPV`!)K4g2)Fo>ZMRPUs!2gGXG+ z3fzbA_}zf9f1+IiFpZ#B%TN~kxix`dr<cwRPQI5c(|n3jYFns(ELozMqSkP_#J=;? z%UpXAmj~ldv!{;LA~A}cNB$7kd-DYJ2B@Um2Yft*a1xxP_%IOm%{XnQ!{=B@uiuv% zUVRs!NKG)Fe8iUV3B;?dUY42hR||OfY_`+>(`pRaX~P%gKpTfq7v8b);l-%GX)txp zv*mwj0l=Bn0jXJKj_<|WiH-xT=oIv>7?miSh)M4EQo6*8@W<xW2p%BvMmD-c?I^V^ zFyh6!J0<2SFow%TTNAQVoXaqguIRL!ahL0qn>5l8nzRX;9~A6m6XPpC?}LQb4_;1C zS^BfdX&WGC_>S@tQ^n+Zy#^wA2B?=4Bk+&Grn7TNU*9LN(h5Kcsf<9q6DLlv*Em4d z!NmCplyhaiD?AXB&td-p>1+qD|CKshM*<lqDp?J`&rMEdPqJ5~=bk??WW+dl_i=ym z+{|qm;rxD3_~uu&9uyyY3x<7R|HK<yiovAd!oUeW2y}oywa>nv_;Uz_*b$V9_&>A| z06gSDnj55UTRidKFE#Mh|1^L1D?2BS-8XJ~JuR$&3|cY6>s!$699j(?q>KN!3|bn# zFW&>7uVlM$i-x}LBB(1Da<kZ#BY?dkJ$JIb8<mFzjN0I|m5IZjJpodpSvVR4l3Y(h z{bLnK_9f*4wr}sf*R^8GSD5nX)+(`+FxlLBacu#jqF=~?8Wg&WYn0!wo1Vg~RUl{q z#;9$4L2V$ZMp2Ub(R5TnMDJQ(j2VXir6xZ@$rxXUt}eNppa(?6ONF4sME-UsjmCI- z6;{wc36_H>MAD}2e(aoLL5COat+z)6_IVGJZO;mbrAk;Mo9@>>HZ2Jo7|-odMjdf~ zNv`hPZN}p<OUeNXj@f$ld*Z;`%TBvn`JKMpV?6j1?{Ku@#z^kSy{Wr;!>P;O$1<bj zYe;{syuQWQc1Ets0$17GQj!{t3S5I*eA}<&ZOG*H?3M~69?`|wVd|Ic<bdHP&vo@# zt-mSd5w3RbZs9h?EvG`W6f42~hx37aTChwL+bUoR)ge=ID(Fv9xC)%=1l%7jEeK`& zYq!vwo|IA6Sj^PCuHPlrBray~_v@O+g~7zAt6@jvb*JK5auFU`1B6Mt#IElV++*3# zdi%JdQc1ppT)Fn6TH&{hyLjCDk@09j(cjHnI_*TppO)SpmgbD6Kdri(Seyx(^xZme z-)y{dF!vB!O_6F^aelMLYbY)M3skk_Z*2wO&WCJjT{e|Kva$TO);HYY;6pGKIRAEZ z*%HV)9eBrm>BQQO^mSXUCI9Jt<!HU#raWg1y8_QIny2W%W89ybK6bE){2st99c1o( zx<n6PES}pK$%nVD*+}vwJNh*?=g^<FND_&6X%OC6DAZ3W8LqYYqu?|;NT)TSI0Xfb z#EZ-<1B{8deNj?%No?RZ_jMpPNp~(2-{dbJxR-Z+fy@6L)Qt^y90eOJaCqVlti+{F z;Ud?LUw_v+XN`S=>jCDStty0gy2Nt+$Q28}MuI=U3{9VHo<|kFicx?YSQc3635j+s z@nyO6YGw`tA-Ci<be7d7bCMgxXL>#;o~_&}-jzqP(jAp6u5ss+Cg6TxY<;%JHqbJd ze|?gW=TI>glHA*gfVkTWgX$6=*(=!Y2EBW*F|yQ0^_7cO4asDwZ&6=<<>3&1f9+4? zCz70Ar|%^GTfe$3TP)S?`iE`M_mDzwD|OJNV&w#<%&UpHT`e|$Z8O`;!BZ;qE!eUp z{sTZN4$6Ch;;M9+J&?K^){sa;+;7L(J76t7_j9jS0fj@eWK=!<#>XH{*gI3D_Of>! zrtL2j>DPRcL(Y1EoQz(QG?e!7v$Cx$=N%0N))sRPFzdtsA=&T)f7TIz)bX$0C@*T9 z8+%+jr#`S4h~DBS&!j(@)QXofzJ5jqKpwCa{Zty)xl`)vKvb~4-p|g_Qr~`+0|d%_ zxU6T{g^+xq>{&|t16gA;%1vqO^X=D{s}9$qz9%LCy>;eOxdr}ZN`J&|NB%NN$lMIT zh@5p!LPq)rS)Z~h_8esEbcXx8zY{iLv+&hw-_}Cw-<_2%S1h)guS;#KlA<i7eH7c1 zR9^IU2GzS=SecuJIm+Pfy~3MTI#y|rYoWA-1E0FRd<|6Na=*O>iNu_|za$l`S$i;E z)(&fe9`wh<ed>d-<7ec^RsFV_g2-S=!REV1{Xk|)LlgO$is9%oPo{f9%~Mt=%b^SO z2?Mvuw#b2szkIfEw-TEs!KaMTas)z;21z=kxMC@4Ts%)I@3$3^r}2>_jrpSn16Y^F z&T1rEfeHdE=}&X3M6z6m$#v*8mUi8qDb{y(=>~`$`UIr+=<JDDUv4WD3c(@%BjWda za2gf(BQt(ure6pfcfuks!!C{D=GWGykYE9jsv5&Ew?*d`QC#7E?BVw=3aWgc`eN9c zqxMME>`X^b#yQ6XAX+9CfYR#bqgR~?9TVyC$TCF{++sc|da6Y_dZ+L4u8{;O25qsG z_DKdzwD1@I-^?`e5rrWWPyKL52@VLLZ5v6f5YJy6EN(Zzb?aE!5hDsfB2rsh%V1B) zboTPAV}3I@bT3vB=rzEf+P6H|=_rso*KHjKVJHj|zP)0q{>Y8D9gwV)v7cKh?0uXj z9XxF2lYLnerm<u<Jd&VKix%HhN+%C2RQ;eQFf@_vUqIs{ePE42hn=Ze+tYHNZqVN- zKZwFc+{Q_%Jv#B=%F$>prA1;{+^&NpK-Yt9l>j^wNF5=__ofvh46#{^Q{L}HD3G(N zwn@)baZL2ZI|eB+8Z%sApiy5|>FJO53D1r?7b<`q1kT<F1FhiVe*KQZsfqUfC0K&F ziA}n0s*XIZMVj1j`>juvQCUJ$rzQ^5;E{kKcS`^PVR-NM6_IfvB@0_LUzOXgxePC8 zl0RnLcD!{{mzJe7j)dv8;-B5H_sbS-lQ8AG%a#y$d<0j6AbON1L-G<?Yg0=hgn&4N z>%P~<y>zJISPs5RN+25=2X?<I^e?ctxbRkDfYZ)U#cqkssmM=2oWP>4aTVRob2Syl zSX9+R0BE~=JF%1T+`q-y6eQS<+;5#VN$hHdMe&3BA__mQ!b*K&Wn+e)3|d9jRIl6k z5ggIgJQa8mROsh#zX8XfZnF?1jZ|$b{2bLLl2!3>UwKjY_&9`P*3Rv^<pvV+w<|P< z8@Oqfj>NOCc6eI^{P;CakPXs<dCfllEs5lB^TM7d;P@|vcTK;(^Z%km$r~^?!Pz%D zwsUVsK@dVuSXeQyTkg>NA!p*~INCv$v-0tn6($QKm5qCv)Q(9M>YVNp-;+<j7R#HY z$qgo9__nFp3pEX*SFYbLt5)#;qAYT_OOqL`-4YESn}%HZy0qD1hNl%<rUsa68Wi>H z1>-0Cx7##(D{b04Bx=VOc~{f#8U4o$mNp)4DugJNUcYZNoDxqT$@UUJi;B57p6iNg zPLGm*b>`+oRv{XHTj2D7b>TVS>U?4wp5s<zzZ&A{<$*aJ`-YhQT)~|WKK}+E(;Cmw z^%D+i{BRi=d)Wb{M0@)|jDc`+X_)Q&%X4yhDQA3o(VT*aHNnRK^gU?X>B)%>Vm*GF z8CEZLKYb44@zA*bGsclC#HSOt<ArOgH!@Wp7UEJ;)gZj)PR=@qbJK-GJ2<DU1@=P1 zKeG|ox+C{`nI~F9l)Cg&s9z9?+44P1B3b2kGtE`B!pFrgT?L^hjo6G5WxHb<vn9de zDPt=@DuNAsBv!rWG)lk-AiHRzSsmJUXZGTIj<duAj2<f!#kQ=ZK!97tuJZ};+&f+} zJ7sHTo8XTHu97JC7;f^5<x4-)(u_QpcmC1mraz`&W+rzZNTtb<lC|Q`w29qJ*UzVC zAr}MNgoW7E_B?mrzY83tu0I{6o+HB{kFY!(G0p#0<^rTb+0G~z4mW_WpZQM&?pzl^ zU==aDuhcAZ&Q$XlGDlNM^#IAbBfC|TOZ?^pxf%p-i9m-7bOe_E9}<NYMl(hmTvNzR zZdpL8OBG}z5`l-<Q=%>%v;L*agzjFn`4XLBile~5t9-^b4G^pneF{4y4stZ_(8!Bg z@G+_@@R?iLFB_u1w`dY~V@y9K5Jqis8wU=s6r8P`>N7?mGniqPvByojvO$^@`)o(S z0)@=G4*30{CnDQcZKTa}DjmGgz#ZGy&(G@mo&i0U9mW0hI9c+TDs?z)u;A+r;NaX6 z<^3_%S)g-ZJ01C2#nBF!*uN-$YX8}KL9oQ-wSiu2q=fCOd^o=OW*Zg)1s4C_0oa%D zaCY6(K_{k<6Ud(pt)y-jLnvOtvYpw*?Ygw4YHS*T+iB%mmj*1+HV@s{>+-;TSU*Jv zd5EPsT_)v|VCAX0Riel{uDB7pOuLS9_5iBXzo?xBT#$?Oqj|joS?}Qpev>6~vhj&p zrxkk$vkXiawt&CRz<0UZ*H?*}kBxA*7lfzynQ>P0NDXAq?uvewOTV7T-^N?g>UIMG zcf`ug$Qdh|=q1kh7upnFwtS&qE#hnlRD1>XHt62<v(*$twnS%p2ukr<-%v@;2B?I? ze&r(vLE1>a!%|?{J)>dQM*c4I(Z67amjb9^HIc-7q;|>3s+{`!wTcfo@ajwqmvYc) zAaYq3X{0136o1pg9v@Y8&To*`{8;Js{@R%RaXOB>Rg(EG4i#@z=9;p~3kom+oDt&r z8@&8mUxbe&23a<0L{0bSg1a<uVr}mUOo7w{({E`+HwhD)N3IS7?zF61l5i@}<_2in z;QPdXCK)mf9(yvKP=~meYH$jTeCL+bdnE4=f`m43X4U4p^!~Hn4q&p(eFCHEX#ziN zg4dHW987vpeb?nljRF+r5)cN;459KJJG~UK(e&xE91Fol$rsK)r*}vB5@k~!XiD*m z=cF$g%HNA~>U(Wr#df)^SW>c;*Q!bq*H$yq@b}{bYZxa02+Q6;tuCmmYQE}#9pW-D z(+!m~_KRVei(3^xT&PMPl$8A3IWk2<b0v7h7k*RW?wS6>Jx&~m_nFJyXCt{ZhWUf) zEbYr-=nil7ww7t(W&ez{CVaU)uw8lEGx0f@v+FUwQ=`JMXG)3SQL*=?hH<i$!@d?! zT4Rr>vXsPk%q7eBLCm;?2*nVrrSuX2Ow@(D@Y6Le(lJZqsbincX`h?=<ARX3zM(bd zse5wCoa%3ouk3`>I%aOWyU-n6ub_~rqw@94$8HjB-Cw9)sLE0El-#O*l(9|`{ef{- zu5S9hNquDA4?RzU);Qi7Evx9)|4vY}@vYII3Agrx4(oov`+d{zO6%3-2q~=WpkG3q z>sTj0O%;S1lyDP*?J4;J;vq-0)j(A1guE(qFEL{iL<O*l(@)0r0{fPY0?A><A^vKs z-y!oob`2GB?4_3Y(qEsAqU={si2mSh@Z4vt9(^z9Ox0|6<su@Rxj*dTr(F==V&KDh z-uOFX1B^y74|{X90?l)>zzBi32M6IzbUvg49Ni|<j73AA=~tzjhipU2*ZT&@*r^!o zV$(|<hg|F-(S48JTI6@cN(*X~Sf#YgenvTDpaRCGr<7NMh!`Ng;W5yi-g_b#0y6@< zE?a^+^6Zzi7&El8G-4o>wiu~qov}=;s?>BScFng`#{kW5U+nS0d@T0{yy9^EN2;W0 zCH&hFauF=~b9&ulc++lxvalc4Y8jMPn5$*c?4S7%h2L!i+J{tn<Hcpt4%t7tR(`e9 zyxb^$t+~ol)->}W;KGIlKFSMK518#4l4S6}$1B9_mptr&Yb661X!h&a+Nc<w0{{<- zZ_FKIxj)aOKscaTEv6CHtI)rx9UBKvxsZ9mxFYN5pk%&|LyA6<s3gUZm<eUwlUTGV zso4tg!P@l0!*&aao&^a&&fugUN&%7wvNhJ$DgrLGySwV2G?X836wFZ1@HdJL!;J1e zJf6@1Lx)mJZblCxGV!C!=VpfZa9C{E@F0`eMLAdN2n@+BCvd8|XBV+bq~76UyYvws z%S92*#5aF<t#7=oUN`rd`#G5=-9at)PbGn>_ifc^%B=m)&vvHOCLmrIVpo(5zg;Zy zwS^LfP3_W8uC_HEJf?IOC&`MMC0#gnKAu_W)u6s>{SmL_dk<QNH9QGn7Q&tdbu7m@ zTBl$=eouJACMoL01y#pqjotj*jDMNg*>GLn>t0;i^YXv}mjmjj@hhL3UgrMnZ~IJ! zRE}+h#hsK@ZA~9mXHA|T*mSlIY;yJNsR9jaW4j$~M&*)4|0opiAeLL$FHI{-RcXC9 zdUz={Icc<>yE#dg6m+{Sf4FrFooORGo5&;qBs*NIg4HEI{AcrmK^B=9FhShUaeC;z zpF`E>ig%zl1uGj7w%uLp^-u*XBg}Q?CSZ_e$JkLr@nvC9gNt1oZ~J%+Dy@N`d3H;E zg*0k7H{{HDphzYC#m+wpHSm14q!2aR15sGR7%2-LyZ0|d{cbnHWmb^DPCrI~pLvGx zsLvZ^Ym6p)$POI&nOm(wJoT@5Ur(u*9a|h$1!MX(g+}I=l0Si$4iaD3KX7sUq--)8 zdNp^F<V#(>1GCryWid&C6Y@Qht}#r|Dosq0542+IsJb|4d0nb$BvG80?T%_b%6#FP z_#?SSe~CBoH!e)C+!lxxw@dcPNSmx$wpJ9S3kug-M~kPc!fyH)I85Iuk~9mv7m<G? zgU2D-$s)gt8p{<Me3X+Xu3+D><gLSyIzP6Qf28dTne?gD{d#lU-k6SP+~?%=nUd;D zZOwslxJCKuvl$!d*z7y9%nb|5+;g?jZ<(KPPJpfmRA;}mK$KWBIZKM=Cs*dBA=Wh+ zJFQc)a%Fm-)V&=?WeWrIZr{H0Ml*3iZCDIsLvH%`v!6e_aB6gIY<=}hWu8*C#WB+w zhi05a=g+l#FLTYM`W-K)%l3;xHH91H_hbz6yQoQ?eM$Z>6~7C_5$6%WtAX%wjn!m} ziuvSEE{#XD`8?>p_Z@BYa6w};w%dumm?96yfc}-i`ZLWqOYO85fpQaKhFX!&U`Kn7 z7gX<6J64<itj$fo2H;&*CA#rNP|TsP;*2m(Up%&p^aGi`tDJ^R57mkZ_|CoK=S!xx zCXOAl25NgO46l~&<${Di+ICjE2{w-yt_$G5#J9aK@Zr$^+7Ij7FCH+bfJr!iuxn;P zXRB#BDEHHv_T(SsWjrVBq+hy(oQujT5*r})no)wjlXBdu-#UPz!zrV&psQcjVTBW1 zb$i%L2W*bg8T(CZ1dqqoPmSb0G9nndEVQm(DlwAlN}CImi)yXA2s3CtsSOKMw45<0 zgY{y^CWWnRVW6F^;V^Ib%&+Rop7zPzYn|w+z%%8r&Ym0D1!o$|%i?GIzgJAPp1ih} z{Tz!}{?%iyN?nqD)o{kk!3)l&l}aWzJC?q!ZLFMv-w~TRHmwFbV(MqhQ&?N#umI(t zA06?vWPcsvaVEI{o3!ZANvxV!s6Tr*$SgSv7WXi&0O{749cUR@kEp-5=M+y5chs=? zvYVP)US6?-SKvoz$Ew<bIjEMm5SS{o#}2*iwT`4|cu3OEaileGB)m(S>HKPFA;!VA z2#BWpZegY~>x#yG!{i`Ls3XLKow?&r*xcGm7ustV`Rmt}mWVdlth?ng+^s%e^Tla{ z>$M_PS=an~=4toh$9_r*?|GlAk+`_Bva-1u;(yfhl(2(IZ@Tim-QkixEKrh~$+CT= zRWmlY6gbKF6srz(4?UlwT2UXYll)?D#Q8@ot-~j4POg1?<n%C^`@n$BJxy}t>y^sT z_-;EcpYPBU^$rpyM-C5wwr`+~^pt&u5M_~??H0NNbO_r#@!FKeT7G@sCq1)lSvA=0 z^)5Gmj=KY$mC<ZU1&GM9O*^(y*|8<a!^mmz7LFGTnfBkv?yXZ_Utdq@*>N%BASkvk zTF2gR!L5c=gBtyFVU=+9I{mBZ+!ID<t+sG1XoQh?XI;=<e%Dd<Rkwd}Hy$J~zWB9G zgPlkp@V=kV2Zx4&x0l+=J_RtFPuQjIBM_`lO>9&V%mm&j6u757c2C%f0AQ0)xXHt( zp}*pbstX;fe~A5>0+5Rl?EMxT|HBV|KJnMg0jko$&&xr<7laHF_6<c#rm}osD#MnZ zpoz1S*jnC?y@{>|-nN;)&`|DT1kdDKIhxL_g^tfa*QKu6U~9C*3LD|{V3!@~pk^F6 z=3T{d=Y#JkCm1w2_eaN`_UXBF{zUF+Z-cUca}F9EO}$yMhSz>0&%emO!ETsc8CnmQ zQ^c}c&sC?36&liZ&DHZ>1m~$U6nlwVlQU~pIZ~TjSn2aJesHV5>#N2$JGq8pGw0vM zUQP{}cl^xVw7Iuw2fC&mKmGOauQg=YBtFP6S4p1C3@|B@C7XyNd#2SMy-zQ+dR^q; zch919s~cQ2M&NYLhdfB)9rjH_REFI!hT_T_21OEQ$@lM0jbLh|jGqq&UD|)3QB(x< zIDEO%9P~rrTK~0lMbkf9&|P_iguohp-E8xVeLr1J#HT4@d*nCp*>AiTwpN;ZB<bpE z67OO~Z%+Gd+Vmr9Wx@;jir=m9h1o*<e{G{x=FgLj?{~|OTTgme7(FxXd09F&Md&bW ztCgAxBbUKc7rpR3J2*iFV{nrrqz9TeAMh_Un{krO#6o|o!$?nLM|=GUQqr_P`4TRZ zD-Oks2^96<a`}An3q4%jwpPw=+&|sY4PT0N6&l$;tEb!R-ps)^1Z>Y@2{WxUsp@K& z@wxoB$|sggofm)E0mw+@G*_Ztmb$I+tFnIC@Nl*Z0FHl~VeWt~fj~;J8@Fqhb}pce z6=kU!u#z2{{~{z{>2J@c2mh<^lxAkHp=scD7rO0v`(JjUn>~>lsLObnvE7A^9k~D1 zh3<xbk>FWv$>c>XP(R)b^X8AN{FJBXYdb-^@2yW0d@{%OLDt!xBFJ?z`9JNwcT`i` zyDl6AL{ULS1eK;V5d{R1UUaKS6Dd-pONoLANDU>RD2N3#^cL76AiX0!NHw%59gz-+ z6ltM_mT#^E_ujwnoO8c(?l<ljXN-IDha<$5wN~bu^DWQ&%=a0M^;eK22o3^`z@sj1 znCbRdkIRPpwW~YMRNqst+q;-_RWV~4Npq==a{SliZc}IX=7*KK3Be-4W$(==c@JM9 ztv7HHg^#bj&&#%6<xVoDL{I))RaWlOFA%Y=<k&2a>uuP5iCsNG4|ZVhc31U?8(Luz z^Wo2^hTA{SEY2R}ZQn8fU=F;dh+414A)q0*30m?0Aj`2in(KOesKjp-t#!u+Ot|4` zFjs_CR?dhVPU{`7^*$4Cp5I#c%%I|MeDpk<f)j}Ds<&O+0EZkrFQBHgYsy+FlMYx7 z9?C%d^=5f)(bLoLEbJ>9sH#9eF^vQ=g^dkaIYzTTx2}{fj@uC{g5Y*Tq{Ac0?vPyI z(qdWW#a7&R?r9z4&D?<P;U{Q{jZsbm;I$1|?qaIHN=!GGb8IP}vwUQK_&t%=gtO19 zqF<{t@(@Qk`(6o7{=6_pBTJbe{&T=)$#aDk(vH#*>DGQO2%z<TsT?C#Mvy+ggpI|f zJ$bW~(TKV-GkLLTae`Ol_<>s&*SLSiU+@RF`tyZ?AA6f_T~lgs+V>^(T@AYAhjsCq z+p^Pktrbe{g&*)1(Wk2e!AfLPPuTM_l42T{Ytc%r3Xb$OXEEN$LA(r*A6(9q)mAK) z>^_X?<MrhF<7=)JP#{A^01di(%G8mZLj2aC+e^`)OU6SQbQ)9*y5uvht&j#?uH_&B zm6bhl?E5%m?I~-}t0<kX1O}sO1UO@cB{p}|nI+GcRkaGAsw!QN)sR_pf#2dl9@>sx zn|gy}A9YH_0G$?PpdPrx{55THClRsNf0)VP)!L6-pkU^r=v{r+<!!;i)q3+-IX?^0 zvDk54#@@4fO&sSRMMnvl06n_2#KlLX%|tY5wNnxUgHcaJ+9of00+|;E`Ym_ZeG~== z(FDQ3Z1|c$(M;J!D#-z&yrB5j_1@R8-I;^kB>SlFU^rp16Z3vvwiNHRy|J~$5jYC! zJhRGxE)HLRm2-k-@9+6~B0}ki6jIG$M>sqkG1KYVGCcU<0~`OMM(!FzNmtK~+2%X= zSc@_)3p_xu%lIOmMum9Iou{2O(wezR+?e><>Sl}ulipEdReAp2g_^hLDwi_$P#WQY zGNOv^G-<VWR5MFoPE%tDwDP})PLxwBEjD*se9a$F(#-pMla+h_G<Gd>BV$hy0oPA4 zBJsA>QeW~npJ^0xq60*NNr>&{pi7!nq7M{qer+;15A+H5`14a2ZH|IBYFz^VXO!N0 zC9*+F?uGg6Ma(^C(GZ6NNe;V*R9SJ!K<ip5@ff)hd8aG>^@6GcjTp5bRFaD50H-3k zX!L>Zrm%In=uupIDE>?ptaQ)Xm2$im&F@v2s9ou+IrwfV)*!7aw^|Nt`BmT9s!u|f zn}yf2RK}gh2-cEV4>X69d3MLkXLDCtkP`V&Oas)9pE8QnJPo}4Z~O+bdOzELxt|KO z^irs157i(aWV$sOb?!CprLY!P@JuK<Ce$f?g{KyA@X8%$si^YG6;Esh@m`F`F?~tQ zN&Yu;dVR$PCv%nYr=VH5AP(}BsJm(|TDjwTQ_<GA54Xd{=@x~sYEPGaw{SeQo)39s z?jAm+#k@4Gk`lOPpd-GOCmGGeGEDrIkUn2!3i+ZDS>Tf@Z@oQY7Tc;A%l%sLyQAG% z1fL>%RR1M5q+9ry>i)%%$8U1S?bqLNCPv4>7YHlXb|S%I=2|AU=Sm9E-QxTg9ji`$ zmW($z%Av7(3_9mw5M&Y5Z$%Boh$MET$NUOp?A-ozKb0KTmEu1RS_9Z|ZS>5XNHkUm zeD`DLtmiwE1CKW=9-g`HC4{#23t;2#<rC4>A?gepC?!~PL-ThPBw8I@p+Wo0a^JP? z%u8)a;x-vnF5h8o9Ur>1?U#`zhSwa8xTJ?R3K2|mtTO2|QWxHjKVsW#Z8xMRaNmCG zYzu>%{u(+~YI||`K(vy24gf4*o|lDTJj);|2fJh4k5x%~G!x}J2i-51__!m)taW;O zwh}+zR9*^4i9cTqkCNH?L+Uy7wbGNqun{GSrB6(==JH*thfmxgbp9g70d^bl_=Dk> zDa<EW??lAwa9WariKA~u21=KmdqFc-kl@OK@A?7p%eA$&e(fUBp<BK?`j0md*S!>S z(yZ@o`dm>KKqqU+H9pLc8Tyf0iEcf%QY(C!^L!`**{mb(o8DR(f$~&S%q<u19)4D< zMcAOd2~Jxh=M`X-xgc+)FH%Sd<vx7t*oPM8t;<|@h{Q9`;NGvE%fUF>|8|4R?Pw*F zo&|HZEE3`fl)~mEj*6DsdN>XZmaRD{U8$7x+e70DF`s|~?F3q&Ngja5wCH)hYNnUg zdYxv}_e3@LS`tGb(B6W>zWR@h7JZh8Brr4XMEj<U7vkNHqv_{c4)Xl9)X^X@_5r~= zQ{4h2Bgm82zpm1H|G^Cx6Cfp&7w1RS5;BRTfdpD0`6`Mj{-`IOa9V^|SqN?sCLOgR z>UyD!?qN0WTkgX-j`6R#9XBPaLNEj@Z|96fT_OUzzOPb9-Jj|-K)41O>u0n3>b+&` zw9up-C3VRGYLgMbeSB|!!~cP*{IFjqqkk)|wr9!7x4LdOQ=tZQBX1lMUUNs`<YhhK z5E~d4KLZ)l+m6+zancEY&V5l?X7{h9+*;{*;6vswv^N-Vs0u8rPeW67q<|Xi{jYQX zrNb7`vD3ek?*>;sMQKrt-so0homjmJDqEC3EFGSX_j!9oSRKxvd!rhyp+(GYa^URq zx{i6OhLVI=v&VRj6{0TEnj}(8{YZzt?x?eXug0wH(c;Bm>?~0wd@G@#(TaqMcPr4i z?V$7HdD6=7R2;355LLuQ=pRS9Z39hsQ3C{|`W^yQ-``R!tN#pRL5_Oa_<FtPV~^{v z)LqEq%>jis)FpdUP!idG@|JhKKvtm`&22AaGP4kibT~84{8w6DST6K6U-Mys>`Z0e zca+;ftKm<LM$Qcx0~z<XBeq}SWb@KsX%q|v<|(mQ;IBOxPS$8+g-6T=nqM$8zTLYx z^)mbTE1X)+!!HbPvjh$AYJba}$|5z0P8o2RIrV6p3!35GD}Y2>VY0vQZf+1}@Tfu2 zCI#0_-&8>mWciWXs^8@Bi!43;|Cx(F<$H)&#oUXxcwqTirAS6&M}{VdPM3XQ)UDdU zm|tci`<?m*rWo`Qng=?x$^Hi@6+4*8UHQFY!xwFRr1}`~h)g=hwMpi&{jF@rvr^+c zN{U^5$4ou+>-J3xJy3W6WUeJ~7%uF5qsnsp=vMc~IX1RMPx(jgbWbrqzWj_Gp8R_X zmfmq_*Y)TjP9tu#&A}XuPikze4f}yC*mq-jcGs;ty)Hjb&@TIy_Nd9v>riDfxVO!1 zB)|y->dak13l1oHrrFS|?%of3Ls0~V7Q4UMO&HB3A&Gi#%&-D85QW;g0pus?e@8Dg zcLA3%Zz2&0$3QRX4uDFF9R#FBAUP;VO|xN_#*i51x{-d27^I^IUP<&oNExm|!*-7n zAHf!eW=XWFyScVws|3<An3|FQo9O$mF#Lc0CTTY|U;gP{ai~rVh`qm7N%h;ykhY}G zx);tr6KrhGD4?r_XuI-^sE^83dJiSa0%)HZXJdvE^t?eeI>qs->P&a<Z_W2GdQSz) zFRaO&)E!kf8uyWvy!Az3hV<fSg>H!FdG5qJ=mciFTgPwWUlC4_%9ou1a&-!=5gt`k z9iBTpoLj1qitp|T*pt~?_`wb9J5tpLcBuiUl5YLDByYkl(6<<!Qbu;3%nYkgiCLO_ z!e8O;iIkCefx@~vX26%bkl7{3ob(n0rlUWDC}UH@U&&+XWx*0tMkE#L_g<`TVN%O_ zH0WXhAS|U~bLW`kz5CDQoU2KJkXgVEi%NXt_pohqTt<wu^3oNgec$uv0rz6w%o5!M zW`ga{J`hIe@95-~P;}o<KY5j_4J*G#&4{gYTO)66u6F$rD8k@9$r~g24A^^Gte=X> z;~!^wJK8thXdYJi^Jj~$92kkEK44K+Yg-^PzZ8I2)TK+Eb;wio-4QBY45J;pMK9Tl zFzO%|I8;5J7`Mx&<)F%A*JRRrf1r~X3rmxCj8JX>tvN0^U)PH{@1oj<73c4DDn?I( zA*fEzCJE}S58jMSZ^3hS%hs^=g}%<|M=}4#fe4!24(%>ok%~c%hg^?jufF1=8g?)O zHE!MfBB5#?C9#(sip^m(5SJFb{P$A9Nbshg@<{IMV|g8##CJ1p2Whi{`K>2$5mC!$ z`tK<QS|uXl%JjX@F)MP)?a&TVtw_-W^tE=r@F2?<EcKt?r4*K=qReBwM5eBrSj_5G z+w&U~%YRWw6XaL&Q1wgFDuF@k>bn$fUnrB~`w!pCdjbmaX*lLb*)kGq80!U|7pL!6 z$>WnUCLp0`t*FRj@>4DhrQ%fN#q3zl{ytq7#RijaUaGBb+hDhU06pELz37;Ibe148 z|73U5pP9!gS_a@MNxV2TEjmWdJi!CR@ewWq;{@({(bZ`4x>ED!4*Z2=SQXVSxlVAp ze7@4!d2F-r@efu9ek-JoF?TA7b_*<T@KWA1yL?5l^XrOKQex^*Vx00Y;!hOrav$4~ znhJ3awcgf!f92ns#~k&k`8OYwf9tvB3GQrVB}Ke6;~RKsAA$p&2b~I*UPcpo#m?$3 z1(+ZYO+5oXl=!buB4pXp;MAe|=QE<*O_E1wQ=P<B8voTT89C_oq}zaz1wEPiwHFvC zaVu{Ub>fB<<aLSdX*ApvA^42My&Q=Jf?urp|0e_g&t%~LlXd@3)(s&V|5s++z@S(( z{7$^TaL1U5-jOB~3`;-YOP9*Uv4v0fg$;uE%v`Hro<Ezr<5fzJ@CK`%&Qi?rMwY~g z*C$3cs9rECQtP?k@S%{V$d1pMk_=@dDdNP=1NQA6@(3?W1@%GPfu(Ud?<0hnwKZW< zSyOjpZ=tI`2Ww459z{3Q$@EH(n{J5Q%^q$pjq27>nhASFd8vdG*MgbxO?Q`ie>H4> zzt+g@=|K&g<^^LUk?!S}W7f?as$^@S0J_as?msMQm8rJ0pI958N>1Tbe>Y(q3PdF< z_3k+7oBmbQ%68{7!fjcYVp0oJGZ;5ngV^GW$usq@1|NND8g~X^<8>;&<FQnk-4}KA zGwyzlJUw?>1M$ES^o2+E<dyW9-b<E#@R^v6H#C*+fQ1Il_BJ=Y-FciYP`^3Dh{~Jn zCr>*+O;MRYj#i|voO(jzW)_34wuK_-mo~@anq7o|iZx(PK;h!p;-u>@MCT1ysW=s0 z#}rSEtG6qJdLTu&N&~W=jj2V3fZsy9uQ~kT9d1XLW86Zy=lZ?y^|dAX##*aq?pNiQ z^Gin6n{3BC7Fx_}1HtMxGI407|J#MX830g5sKxv@ZZDf>>)~H=A$wr`KNC?u-~{Ec z1vXQOJqM{pfd1Z7Nya-nX~vYt^!31g9)AIwKu^F#8DI3Y5pxpyCwK{!4fH|wd!9s? zg&Z4z3ztD_&x3UUJnVl`gQZR^*qhSf`8qMrRngbGME?7qO96PNUGv<KlGVW~rM!2P zQM+ZWQ^eQihP$CQ?9vzNdH;)Ve(vTF3V_X2C#I3x#6|*nbP6MZ%yA&9i^ISS+2bnK z@5NzRAeWh)+XG6!mRd7+acjcnT8D>RK|yAEMz_PuMBw8EB6d$DmGwB%y_CK%QSo`P zPv<V87|(+<M(Q8dP|W~EtoST<-Hp=9m2}K=1=DQ7elJrDD$(0*=E{@q8KaK!3B?67 zYQkKpCoW@r2HouIDW?7_GTv=7^Zkl-FB47_zE@j3W=?bEHTrvQcMnd|jnsT)&vqUZ zdcjJc=^jnR)~|J3mL@s8VuY9G=2)@Y4|xgcf0~oY%YNCD_&s+5?);@UeGEXUFR6*L z57G6Pw#0VS<rku%e1*=MPL;A(D3SC|d7jhbf%g-Q*GRGkpOi9Y3~UW;bZ6Yu?uwo` zTDpFcK1rB5-NS5FJBMYCzKzK<|73tes&DoZxNSG}oQ*e|ET%WyEOLd*Z+Dazf!{`b zs-EdQ5)~VH{U{VdJ#;8rQNbwnOdg?|SnZ%NuF5>w?!Y<XL|yy2$2E$XZ0iL*jMBgC zz-_miR8ln^Q8aW%8g0b2m|oZvwDPZnUyEk8NJnc{MH@T#>KYSsRa7yN&HrKDYV3k5 z8p<cjV*hQ`ia{}d<gHguYB!RGZg&C#_43_$b<&!WHY6GGhZZGpk>g|v((x&Wn$%Yl zl$;8eP-b)&j^BtD&6E5BHwhZ)%pX_!dV!KzDaSqSTGjdP!5%1mg@eOL*53XcDI%SK zGOMRoJ9EA)<2l;-3M#SUgVI+)>hYUns&hf`XCBnj)kw}qguE0xZJ!aY!>zqO-rW0L zmY`oc@c`RvI+!Un$X$N#q*;TGC5Fuj-xUom%Q45^bL)i<ZCf~8BYl6hep2Mnsrmp$ z(#MQV`h_{_QsXolWQC`-Hp+D)2&ic0DFagUwcCowe2Ld2_8OhHto?reL(~jQb}6K6 zga`lN<+hQ`+{+TwMWys?=FTmeosHe4jGpUfA*-MCGCJ5Ta&)v^Y;2Z%eS?0%EAWr0 z*b_9rQ+dC{u{OKuknrC4#0jWuk<l(cB6UCIJ=>%MJ-lIRrE~!eh0a8=QGU1W_m-gO z-ufvqheQwiU2>$jZ8SBPfwbiRdMwZz{~-k~X52n{*molJu0}3_Z5F`7!c{&Chb#3$ zg$U%@f<~KM;$EMwoXO0pn~IVil7S?n%|A@-?8$C<WVx>rluYDj*V@{rSwF$XV+&^s zzw_Q=iQ)@s5|7hqeZI(%lE)Ud_=VkCv69w%@dHOygMu=FGM--(oN<Ye_uz@QK#y>7 z4%LTcY`?gN{v@tsctqKRcqvcYtlLl=%73KMKF_fCJ`3S@XcMSZ56*l7b27qiz3<YZ zo-s203O4eZx};yYLv&%fxr*r<#9Gs%$S#h967{`ephR&mT^BZ3K!q^+h(Tq9Y#95b z2QGI&K8+9m5_t!3p-NIuj<I>u;jH#;xIHw6X%-xPnPYTtA9W-ZL~$*~`;ePatx32j zlXEUz^4qmHp9Zf^7Ef+I)_WEcvw3B7OEPQI1XUanf7N?yTk8|WBq@u6<_EUJep7!2 z@_&j#*d(*DnTH7xkaMlUb-90X6BVnzG4pb?FH4o%?mbI|TrLff0c^T3@TbEfdecp% z*}ff)Gq7jUiTsRSS9c*W&t5li@lhK+`FuJ$py3cv{JF3Mp1dqEbiwamsB1JEmoQ|& zj{u%F3Dmz}noDaSucBav<t~`vAWPsi04xJrxCSAyM=Yp#s}O>mIKOY=6RmO>_zl!D zQ<6DAaO%VW(<7d9AFO8aU#J<IO36!tV~twrZGO+iB^`ZZACW5J!k6Fkp{G`MY9haX zAGTLo((pO)Glt@SltmlmNA9D)Fx8jUqGm@8ZSB#{2ZdN#pQzmv4o;gm$;Gbo+`#M( zb=Mrw@VKw0FuWsM8Qg7`7K}A6?7q@UbRjT&TFn$e=Uac(M?7=JjPYJkAR+IV-}x&6 z^zUq4+biRq_%^+y&gCorMWtMG(%aPZHU4ad{Tu5q0pep0%d4j>g|EeMt)qU8^2;d3 z#NOQX2Mmj^6z~S;=Nj@IXo{%(im$~Ut-K5uwZi5IVPoK+m$6|-6w@!jcG>#NKW!@N z2#J^F9qjy`Yph)#>nD9P0XoPABZ@bBw}k#$i4reA<)(uIByk#4qCE)YgYMYGMD{M- z-d8BkrygOGYuBVP_pZb&aa-?>m!py?@c__}-{rJG7~4NI<aZbH|E2@~-*fx_rEmR? z5k7zj(ULv2cl_1V&D%UX@B)Y)7QwJm?~vUHFiN|=&r`-$?OlbglKRG?^WN8IShpF^ zsrGPm>9TA2=!@I>w@_gflW%ro-pvEI9O=og8?eKnXEWm-Na+IE<kFRH^>+_1Nr=4# zRjMzcQEN~vPNBIhS&3z?oKJ|@+5!C`sE~Ba{>NGBF=L?^RWbsL3g6KA16!gtCY0r4 z|76Pu+s=iKYd@G-&p=ETeQwWb)|snmz4b(jN;_KMYW%Q}pWcV^S)R^X&323^;yPw* z+JD=_SzoG;5-6DW=dNebdNVp5-{qEx&3!I-@YJsuwd`BD`SpIfk7~@)!c(tlk@kgN zyZrU6((LXW{+azHRvABgU3<31&r-2zVa(%Mum=;AdO#4zN=2mBLnqLiR>!5wSa<FV zC4f>?`Xp=cRA|>N6|9$8Om@h?cO~8G9P`d++X>n5X{o(Vz938ngfmbqnpGaTOZ8t- zEFVn5<Z89bR(J^25=Y{3vr&$W#}eHv-a02U^sI(Jys=L=M5f3gKr04Rsc<2CMCx^0 zroNB*J*HVW4gtawJLC|2;@!svYvr?k1>e(`TC-M3x-^mPFKJ)knv1GW{#qC&&{&_- z(w7v~?e(hW%^W{NG^5MzUCI1_M@1jNZ8%Akeef*8gBTWx(VE}*@-y;ZXL_2jTO5(2 zI0ZLqOv`ClXnZ9sGSVLE&kC%NAy@2s7>xU^>a{C+imqO(yUtYF(6pTRk#9=()3{RA z-k~o5{3&7rB$a>G)*liMeT7Wq1**S#PIp*2O#F{ZN^z=EoW1l|=kU+i6G^{4uaa^m z2xcO;b}5c9l?@W<MBpfqNCd-aO$p&({x<;i&5~VylkLXt&YdEQAHbEK9l4rCU7tg7 z3Vu9TM#>)}ZxD^5=kqBs=f82q;E4a1bN-J%@t*-<H?cQ4WzV8g7;C%Dbnw94H)#_$ zZ{u|2`4gHw+*fqyvgfnx2u3ROZ%G=NbsuLG0jKvf1(x?Og4kz&;N9Y5I0G%s#4jgE zi?YDUQQzCbg=A0<MOYlnR)Vo=AfYsId&1eB&|-ERY_y}S0E1%_$>V&pI<;P{l?GDb z4>S4D(|9%fh~P{xydpQ}?%7;K^^Md0COcnJ3)RN<mlxi}b-XK&mRPaQ0c{TB+o53? zYK*qxWceu?J?tBILDKMC$%8SU0;fTaEzfw~6Tf;8+lyt3?_ZX-wihm?6T8s@GyB`s z%)+{(56lRW&;Yg-f+q69WwRLD3lD6}1ln~$UsLHk-pN;dOKP?S@a72yy~tbrmwb`w z!L?qItM@VlrT`(?23kY@x8r3K9Z3b3n2x|B$9bI<aD^M!o~0Br3AuC`X&r5yRFVR* zo99so3LbemmTkbO^&`<x%XU?Tn?Ca}DuAK0%vr(vs%f#?V_&nuF@KclPJmxegNdj9 z4->aLpg!vih2Kuv#Qn2?lJQnHQHee2%qB(;C;xgY7`vdTGXsm<D7||=1n#vuYv)It zfj#XBThw5PYMzxBR#MCV-f6Ay+30yT!^NmB5Yrmqh3>ev1$>9-Ct8VPD#zkk_s2K< zF2q7(`SU3mGz3(3{C9$G@V~Gj<GeERuUsE&sWSEm_(^Y|$kbozIGh}W5ue($&QX%) zR|K=Mk`0QW7jhaowzqELRWZ7w>seD@!WTnB!N-nG;2&6JCd!qZ3hI^qk(874SmW2h zm$sp;s4&fU+kpCX16mSEoM4}DYY%xZGq|4bHU*AN>R9$1T5MQ;J)B+>-4x13R}XLC z4<mpJJ5pS5Wu~;8IVxAwPdaZ_30z9j7;LyuZsA*`f$eg^z<DW5`kmqN#pwA&XgAn= z3sg-4I+cn@KR--$b$iGjHBH_-olHuf-;s#kO}(G%o*2x8atoO}J_DW!C-h`|0C}fn zhj^oLcI)hyO&rVe;^WBmtdxx~ICcl@g7=290#^sHej$$TK0R4^AtiHJG0qd51Bb!z zJcQ6^SsNVpQ17MZN{QRtuN+REz8T3}a`Zd<d2k6(*oXOZ^%H|U3<|=u9>%tqqnn}@ z!N&eI8%AbRiC2e`wA{r<2kB333&MXgXe}n_(@v0guu4l($Y`-jPCqiO>&=}YN~Het z+cpw63k)8E$qzKS9^V8*jWb-aRN|==tup}6`*-|xa-Iwt8?FDUS<ytaBASs%KC?r4 zMfw)$J1McFzNAem3l|c$^}pr&cm4df)w=!E%?16Xo7FoSpgLVck&JNt1(oGMV-6e> z9T*5E+wB9Ug>(m#wEl&|L@nw=7F1Djb{{xU+2!}$JSG!dJFVQ53WRT=*G#i>WEAt~ z_Qls49HDT5TcHUn{dw7XkYrKQ(C}vnIRVWrDg#ZwKq#XweKug;sgxF=Zi9-*LWAuZ z9hEym81u*A5}q;C`kjwY>*}79VR)-X`7dP*HmDU1$F{I}QY?XNlF?s_00&aG4vZXC z6ZjGp9wWX&jNdse38v|M1GoSzUNkzu+%$FLJj)iCSqc<`&4z0I#=tORI}_DaiA~KW zOL!j#H={*CN8&A-D;a{9NOg}1V2NgZ*CRG9>G+SFs3o!x(!x2wab|VgW3FxF>wl33 zsG|eTU-0?|b(89R{~Lbto00tPHzWC-l6aL_hSLr%g=IWeeN1(4-d&=OvHF`wZ)9|F z9o>cw+i%Ufe2<g7o-U*Y@MjyCC!%`B#YwsPJN5?`_^7}J8&<G7Y<_Q(6?WPFZGKx( zoM_=O!`l|cY$SDULt+Q(O|!R^Jg2G)*_<!?_+e1P&!+!T3B9me34LyT&Rrzz0MpTp zxRZA?5Rzz%!)Fj5D%qZ26qNIZYN1&L=_;9Z5?a4{?PdrsLBE(>$|eq&Q>^t#UwCa1 zA9qz(z0O^w-1lt!!lzd03a9F)OU~W(v%`#us~kG2X998ziur=Y+Y;QR;=;R3O0Tz0 z8?jay#`2i6wf0cUp*bQYA7>22Bh0^fC7^oL1L;JnZ_xaFLJcM}J#ALW?iHGHMe-Hd zA3!lwySh)efl3%CE+QgLVaB2ssx#`_drB!gV}TMf9imTKFs?rm4v&>2>G=zJ%W2*; zXOt$2`7fF2)mLIrpB~Lb@Nyg2bB>&)*1OECt9hH{Kg$lwz|GdJhRtM&zwF0i!}96r z$1a#W<$Yddh{B2s+KUM34tb@bQ9WVja$HigN!=n-y*e@F4|lY)Y2&|Kwsvj1<?~l; zGoSM}HUHK9V)IsrszZs3U_;8Ldx;+_;hCgP{Z0DcHG0^6%8no~t?%!0J8UE5vF<xr zBPqObc4pt5Dy=I>v{J&kbJsytl-rG372U8&_WRA}z1$Y|CFa?Z*g@x~($WR4Jw19$ z!n!zsD3}4Av42!WH~FWSm$4MOt@0-R#OSwC&2T;AUN5Jft!2{ZY)N>JNch1gbQkHe zqnbGMBIJ*Dh0RZOpq>i)&cO_*49l;tY9(pB?b_3#Az%jq$E=#aY~Ay8shDk1vNcQl z?0#>v5!FPwng(iQExR-;GXe_d6ig>`^Ny5-SoMp}nV^XtfUL|JSQ=wzm4MNO)-;S0 z(PZLun0ToH=@(M*NY-aih+m6M`U4f(q4F7$d_@Pg6gt0lUrq`woapS@bYb}^C#uJ> z)tw_>)56Y_VsA_L*B%Mqmr|KfQs{z2ZQ8Y6$&l@1@k8o=Rl6>Va%hljf*_s=;<HRE zw0T{U2A26TN%8~B|8bD#Bl4t^Pcxb)EMgYJwCcyOOI%IZ*x8BPp0AJI!)2rIUH@PV zRljIxtNXG{44r&z^`1D_iGbE14+~Lrc=D%GhM(~iD_AZuM<RO4w=+FsX=VA5To>o5 zQ_QX1O4P?Q2=94ekKTK^IrF6YUg%*qg@uY4otJL-;g{q>nfgh*t6P?rv<`8{383v- zL?zGmqwc5ULkkYMTwa;^n0ax2r>_ka8(<l@eiE=2%+I?qCjExhy?4acDp_I4TXQ70 zI6`>6$+z6;Yox9oy+5|@g^mD@BnG0Ss_I|;Ci#knYQNJ6lL*9t&yHl&iDeQ>-6kY9 z&756T>|1qZiH~{6OEC!-rL*yvK(|Eof)bSO{ZK#vj-;4@pA8guEvnF!H?b<7`*3+| z%wBx*2QERzd0leZYA8)=!}3|(zc6JQH~m28Po!MYg&`Nr+)YFqX_f>Yf3rAv{14`~ zo>aZC5781bNxseLl2>YJmg;2FxRr=(tN?ppyzm2By<2;B3+(tca?|+Y_BQ9Sg#nr* zRZv)fQ#87jJ?7Rn#SVhx1|k`wzx=ZV!9PzXaz6Qs#7u!@mS+I9jy(`$ScSAe6&4Lq z`smnyV-Ik>ooheVg^EeJw^Q-iTAdgCJi<_bX)94R#N7vI?B2gr(7~d#)GckWpAFFr z9BnN9PoxbDQ3@O_58EU{PTM?{xvlz;e=*#oj`oj?h2~5~Y6BDyGijz12F!z`^6&n- zbP-`+BKrb?oZA}dL3TGtL>~NpE)=XmAHI)*!@1L$jDPX$onlEtJWX>f;@$3^Oyzud z!iq3=$EB6(4=X%ZxXtse6&4S`D6uLGR=zr`I);l5GSe9)Zm=r-;z8y&ZM|%$k}kR6 zUqUqj<*Olx34qpiZ2RbJ5jXB=yNK5c7Sq?%Ls2HU#j1xM>sy_HX_~)s-%eHEl$TSA zeYL!2gz*Q%RICy`l^_m^H8&PlB_Y7hEMc{JV-7GtMMy-J0Iz8;?W0-?j|#TX`v?Z- z&+6_3%u>hezru0=xA8YOg?iWj9X@IIs2IfOs*rdyS=%opu(O>FPWymH@se(Y!6Qtb zWjCo09eUbt-rZgp!f4SMm67*n`5csO$k##1s2BKhprxT#f{&Cm*QsH~=6a*e6nCP{ z(;BsVW_H2|Av{giYSEAU2oBb6i7t9~Jr5CYBj|xJfh`m9LSJ~Bu$?Kcc5lxPfB&k} zmbpk5a5!e4!GPLvZ=HJzWk>J1t^9##`+V|w_RQ(a33rZaeNE{0iVW#$h))-EnS{&} z6Nnj{WSs9+$#+-txjX_I=!$3`1-X{2p4-m)@@A;nm7aw$m+_0QDG8~8MR6L|>uDjX z*IE)^>!puz1gC(hfQ%mE7YmicV+t~3cvXZ{Ya@#kbK&RX;}4p3=&OotvNXjs9E#)f zzH26+Bo-!bZ~r#tI$zu^(Wxo4Cv*zvHlF=XWS$zl&>bRX-)&|o#>R|zpOe2nxc3^v zoWJXrzmrs$|5bfhjUOeU!RS=lsNJ>@>i7C$ChOdTj5Wa&4YVF}!rl;Z{M6r)-*R3p z;~cp@ict^OEGjSjD5v}!xTHTD;7;y<R0o_Rk@I>eo&`tP|1*V``wnS&L?{buIudp7 z03)AN7A{ezLtkL_Wi|<H5SYQ{(w-%`g1v!UWeXA)l>VKx6}F%@e^H1PZQa^wv%0lN zTiZaNzCeq~$7P<#88PjdggKq3R%<&YjA7s8ymuCQ0?A&lpuOXuPYFalY#)RTE(so1 z4%#IaDi9BXnSvSS4sGhFKq|m4VPR0<rXU7(T7c9yNy`>S^Y=y_3E0T^KW!N}Qu_73 zQiH)qFn?M@^3`6HdJSG~4~d56K8pYMUPCH__o_P`$V~t!WART6i3))2!s7qGR^(9K zFZVbM*JMkUzVs*8dzQu|@t6|*&@6W`>6D2x4;9Ro=2B7EJ(DZu`n0Cdjoe*=u&y2o zn5u7%(>f7ox%23ukMLOl-WUv=6AF8HhDnrrp;F^E0vpWFly3df$=)HTh^dBL?BR%g zlYASd{41wlyFdW0iH$Aqogg_Czuf!mu-Dyq;>AgAIukyl1e3$yC$oEkK9v<`BjPn# z;GJ#S?|mNq5#i9?#PZ0oWoKAlb1f}DMT=QOar^DgPgY~kg+km}Yi{40<LN?oLef&Z z7BHiJ$?YK#=Tsm*qZ5x7$nvKmtT@$EKMCpS-25TcB=I4*GidK|_p}Q%2_aF|-U@5? z(`*W@*tKW+k0&!nXlq6?dVHL}ZUgq+fQ2!!A2xE~5UGdrdj@v8r#?(k_HcySr`N@I zSX!4fT<`wT_UGBwW^;BO_f{SbFQF(#;!6L%meK1e=Zp!;!1)1;@#k4^o{^hiyMyqH zNGGFDc-L$+wxr}0!B8?l#Qu<yUSp>i)AGUdLdAr$#~c9a2^=SAR~JIbf<r99?5S{d zj&=<?ec@E9YgBF%$~0ZTE>j%ca-OM>Z!+Py2}&VUU_5AGAR~cw$Z#f%zJC~86#$Um zw84dIXh7WP$a7Z^ZumOot&Zc((xA@OApG2us}BM66KR)8i1c=Juu1=DzOvGKlJ?80 zeIGm1+aIVbFVg+<N=sIskClY;Y8-fc6mWMvg!h0&@|9bav0Ok)h55bp_RHQacS-IB zg;BM}z;q-~5no&!HTiqf+AJm+h+G;EY)6i-2@ZV&w>7>fEej>$eF4D1U-sw@_aJOC zg}b>KxT@3rd`ksC)8J^p+25gov71aq8nU-~%5y=IS1@H}km(l>-SAKL$f-6njD58K zRVDId^?Fgk&cpQkEq#njQwXen#GLM<s#Lvl=K}PGS=Yy@>qUNDUZnWQ&@IEZ=MvJ0 zZR;7;f!Nn&LqDvd-<;mkcEJ>6_nK(88E8AM6^YM-eO{Ab*B0=lUaK=dVg3PCkF70r zmR3T?7DiWa6Y7>X9Kt_os@u#U_7<#Mqi@+fc9&aN(p|ZE<=S;SFYV-1w*J&Q=I4XW zD#!x8$%wZ-Cb}5{_>+g4#4bc|b<aAZv&xo?ZzF8lf61kT!We-_T3mE?<pDo0kA)WY zwSs_gX%zI}QXHONI~#yFV0$Bt)i$n_EUB+$*^Vs7S)VI0A@((5IR(76lT9*~=mt|| zOP>?1;|D@42S~B@v#0X)XCj85-mjUDG^sLJ@svm7(mcpuS$#bPew)Ct#~WcCPrpTu z{&Ctk!Bjj&9Dg-EaF%T7AXz0H7ntnj+2)u=s*tcZ%*n<tU~;*uzIDs>+P5VpCxbim zrv*zhy8V`Iugw15tLdWbkJ9~SlPbTeWjr2@icJ+HsN_aVnA(fD$0~B!-HOUh4~FY= zcg7A(8yRL)e_7IbzRzBymX<KWY_R_8J?-Tl0E57iTmYzQ=O86ak}qgkzozuP-QA%$ zp}4r+Z6Kmh3~$twSEgr!Y4)}?9(GlDU$ml*EY9ua1veAj!UC&#hFz(5EOR4t>PQ;f z_2g=;JrIr<gh!Wi{n9PG`pw!{-4?+uu29*ShtfcND(>iq%LPs%HE(StcK1w#oeeYa zJRLaL2>LI8_QMDOuIUttBVE$(hq&C$uvOPom{N2|sm1PCnW_t`s^7W6{_A$~FP}Rv z1>!z6guQXf!q=W(H&Rf*T|5}~aklpd`i3g$@w;Zhqa9&7Cz!!G7u-eGzbJK8Ok}Xd zcb;P#$Z}m!wKL1lMu+|x*FDXlL#=lLQX3jv+k!cBD<gk!Uf6p_pzDV|uIX!T1~`W@ zEqH3s%l`ni2nD)CSW`a%-F+dlY3YlFl}B}%W#+~Oj?-u#&L4f7Rmo4ajn&75=5>kH zi}|-A<c!I-m9YVla|`Z{L*5nsG%%hP=o|)zZ3a4V4;0rTbVMf*h2wPE$E&|SLL@HT zzv7;Fl|4*f6^_|se=|fq6`+%+&qLi(2VUuPSm}<K*S?u5+AuoA`aSlPmTzmnm_S{~ zUcQbuqoIxGP6YA?4!+-4D4BMsJG^;sWVXzJ{`&Aod#e=N1`v5Uer5reHt7`hmg8$~ zI=&E-V#}J4zhOVte+F;-D4zF}LtW`ry~~?E%3WS14cO$Uxv(CVx!c?>Hlo0cLW1r< z;I`I!u?PDj*2h^>UUD-F75B(E74y~*m|@Mu+0rk4=rCrM4|4NP3BdlfLwR$}nFrJI zCK`Ct$IX(RLxK|Xa`tj1{hzM<7@D>QST8>`$Roc}UbSA6d(EE}Mer#U9y;iPZPNen zV4y&)hTdiP#o-JkeBt!NOly6yy3m3_CG2frlZqArJP5||mIbp!nU(P)P3-bdh5QFd zC1XoX`G|`+M)8+<j}zW+)S=#pnP>~XPIGeqek{bWEvQJZ40JSJ2$7#u>y`g`2(mZP z;UeLFdVCH(ZP>?_P<~FC7eID^#0!43NDcI`{WC9urw5Y);|RT+R3l+vMV_ue-e2DP z%_*^$;Hqx39X79~$!3Qu;hKAULGrkk(dy(UNfq8V2=VAx<ef&J42kH-bKHrpElcTh zgkVHxVVLg$*ONFyhZTE<#9t>*$t_vIod%P&L;SMlA8hwL+6%jH1+Hb0e#x{uGV`Ul zx#U!dD=vRuvR98<N-_V%&R-6}4R<=;efk4uarfMXIE5DbmF=yIxsTn?vCO%+EUtu9 zHQIUI^}F=`Tf*J~66jc&4|+1yAO$2cKK+=T8i@DVzU_lBlkPIX-5#htdF$SagrP{W zSQl2pvm}}=qY~fLn0Turmvio@q(a+VSVA0k#NEYe(52=vupBVMVNz6Hsn&&41rI)k zWpmGM!JRrzJ(o48>pxM@=fd1#-CWU6pOdd=voOF3N+f3>gmCq?#0mH8{e}GvHv+k@ zb04=;pG=ec)LlqWu62hyS*Abt^=pbgAjxKJz;E{vE+=PVHF{6+(B=;jg*>|5G4H!p zRMJQ!#hVyRka~}QZp|)xEEHONkL&oU7-PF+UiX2;gO{VqSws6$;ZDiX@H>)gv(^Vv zl{7c+7`X({=H|~v4q)K$ip@rcmSiu?Fp!@u`FLV?diQC$wA+(|u{ggA>C<LwV_%Dp zK8+JmL}o}B#<V<A4A^X{G@YEhK?rp1wtq<KH(IRDuLtga8%ZV-aN1yc#0P<Y{1F|b z>@|$&;G0#GXtEdoxS76I%ANL(1mQO_3HMCySH1O%ce~UqXEJ^;P&3PH^vOj>SN8$~ zJW6;vqqi@W_tFDn%VcfQf+nXPQ;?ezXJ+hQeW3wFeksv!#lLn6=to-Hoyb}&!vhgs zDs2jbza~~)_I`Rr;<T?WYrG}O$+f<-gOum0(~^@HfRzGt&j7Fqm|+x#Nsiqt$$uE* z=jY>7O4;L{h~D;a1y2T+mkl_OqcY(3k<@K&G#f<&jJ>YyxhGsmj|ynbHT;>d<gXH1 z;8=wv2AEu*AOFUr-;cnHY#Cm^O4LGYqkS(L<%qpr_LPS@2p`-F8*%!ZUQ!sUnOpSc z9CPLcseCn9u9^?O(L2x$>@7s@$Amz29j_y)0ztSnOfC0w;|`rVzfK)(mj?<{k0dR% zA~S+zTo3FV^Ls<n%D8{p*UwKW5eFK^CqsaRKfga%Bf@`}$+fx$xeRrlSd(;FC@jP$ zU-BwJKdcBd{fH1q62QmeEv|<)je~8QP*@m3G36yF+p5kVzLray)2hT0M*CDkTrIA@ zvS&*Mgi8JakbV@PT^{7%R3EZ_mV5fmEYp;l$|3v1pU*=c6bhHYl$Mw&{v?TGjGs<% zA4RF;;zon+6I`$G8MYVG!46Yghw*;hRm)WGbq<jqiPcA>z8~E_tCqz!lqDz3FMC4k z&+M`{%}^C8b*n_PckA<h$Rzc>$vu@e_LPpo{2)T6F0Y^@h#5Q`H^>gd^abX@AMgbb zC{bSiE0mAH|Nnd5ih9g$YbWqWDbH^+Mk%g=Pev%xV&Kj1mOTH-6D5&p?hM;zC{1-h Qz6GXw{noXds}@iHA1;(>vj6}9 diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_1.png b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_1.png deleted file mode 100644 index 4c523b260edf6cf92875d17d16ea0eefab2de3b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52204 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 Zs|XFOj*)TJ)fHa}X@1P?sj1u5zX4xD^)>(i diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_10.png b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_10.png deleted file mode 100644 index ff122f2f01b91cb0273013e72d6d4d34dd84ec00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51804 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 diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_11.png b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_11.png deleted file mode 100644 index 15c0d87c0122753ac052700dd7e73f7b283b5be7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51536 zcmce;2Urx@7A{(tCCC^EO430=BqKR1Dk9NAauNv*G)bBq+W?G%g5(SaBsZCcmM92F zY=Y1<8IcBTa?bsB;mnyi=iU3hd*40p?eCkRXsUMY-nG`h{`Id_zR=Q8rlY<<4M7l{ z%H3PPLC^_sc=YXwL*Pf~Z&R}nbP-ayb>o3&((JHNOyWl@q*bi!{h*htLVZ&Fio-Ym z&F49HZ=QJhDTcKB#o7E4zj^S37<SqTNmDQZ1fj9J9_|N6Q0+eL&jZD0|Am8BEJ2rc zq_3T=64N___J|q5_Z-RzJq-DZ9)=*riN?o#Ow2*%tWA$uGiJj?f2j>NteisN<_<#` z5lFGMNLxO*rmn1xGmI%jI~ekm=)uTTHRGdS%68ugTSDvIp{~6_T{9S5L#dcMTyn{0 z&`j;fjY0opHi-4w?&SWGv|NNARjqQI<7^L|Y!ZP|;2G&Lb=*c}9m`SeJ_ruH2lG{q z+^DC8I%9e0R{MX9KNezJUQ4Ay2i@LSckV(D$}9SG`&78nE7lj4?PV$^TzDFE9(p4) zv&vECgHE{}iH2-aWE2z?-fiuNF}eG_;Z31ZWa<u<PM5g}HZgf|lnOm^m#&MS7qT%Z z&*t@hyd^V|$WAr(zI|>{J0LP_-)YS3IGX;qfI)f=ma{2jEPZE0!q;C)+J9p@cnCJH z`OyalZ*Ckr_zC@QA50Gj(ISGO+LJ>Rs_pOl^qt%r0p8X>Cxb3n{__C6ew$p~s$i{2 zuahFVF^?@KeKX*z#O|{Zz7X_u0(8hMMg1HQ1e--?xjA#=<Cp%l#r0ibS&vyc#MA_f z)*etlBiirgxYRxz?c;SoBJ)p#&GJA{B{z85Pzhh+Ud?3{N@><E&f88y4N-xZTFz%P z{34*`dEz*KcQ5_;Cwo~jE9{!9KuU|hL#CI5AOwxQ-;<UBS5M!SekgQh`n}p-_Q}~9 z9C6@XUyn%F3)Fop3)8`##U@-a$@_jNt|%n|Sahv&F>s7A%J70m&l4&A1n<0NWqkX* z+1gQm%Vv&@bB1cj6zcqzM5Z8W-Q?=G8Tb+!2uf`Q?uBlhblF;&!f$MB5bxJcE=vfS zX=r9xQEQLU==7>R3COwSB}#hiC<H-^q+GD9@*zhFB1N}-Zq2NJ+FGYna6m4d)OBc5 zq-R}nGHWj|yDyy}fp5u|<sH_tLFs^vJIM>~k~h4tF*xV$ey&ni)S$YueUD^U-0gt+ z5lp9xIed3&2cZYu!XR4Jj?-A#@vV#6U-c7TFeVd=-^KCzfK|4yl<<BeJ#m8kyoV?> zKKq-5CuL{a?ecg1<yY>S+eFvUKz=Ti3<MTB1bJKHIpn`==5H5wA3qA7gUM1V)khMg z9`Y+vl~gR-1r~8>i^H3A9ynxJ9)Y~)pXx&hpobDHA!ca$)wtkC>m$r>G*hUcPVO4Y z;nn87)D$mZjGbBe`T37o1N{9@+3?Ctxelbt@vnF$v-3O<(TT=zJMhYFTGn*8^kD5C z3EYZ1R@onzkYh;f%gzyIGFO+4_A_uxCi@5zT(?@B9R2DMhK_Po+1l}Ra(**nYVQYf z)Yk8cr)h_#r2<FDw}1^`V9lGYY00~aeRS1=@i$2(TO|Q|?`!s3O9eeE78zXPvJbHG zX{|MT1AX2PteJx{Q&#VOxT>6FTHh{)@OkXDt(|g{8qaUsTNmE0E@-+%hjH3bYsD~C z-xuq~lW!9iBYe|+qMO;{X|jC#$f2`qUQ|%Q7jWa+$*HNSjfGK!vM^G=*jlRPgM5$8 zB;WAF)MEOcVQ){<m2BC`f+JR!(q=H+J)Oh^CWXmm22awqtl5f8T3DG$eF9#TUt3#q z{jPrXel8Q+Nx^~TwWH9O6ztLhu@)Xj5+c=)%EvdQ7RRAkC~nSV+xVu27hI=nt_E*@ zOb~4HZxQ?Sz`rGoX8B|Ow@9(nI4#pPi4UDUGe&wSF<q0ws$)kzqVm8djoluZ)Kipf z*x404f#zfjprj&&W#xB=uW;_JEcFH1KYXy_>Pw3)Ck`Z*M=#<XFa%bw>cvM%fit~g zrW-uUD&6*iMap&B*L?0XmWu5r$E55<>6Oastr#~?g++1l)QqGXuV5E`kUPAG!*NI# z+P@6qr;qNB8Vjs7Qwr@R<<zAWdbUF;Gxv~#W&18hGP*4Lo(9`d#fPs&(_t<cX6ElM zJ1KXgQYjtw@_Toq3C^SU%cjUw(3`Wc&3bxdTvlodXlGF6PQ>@FTQYU`n0cs^?EGiA zt_yBQwf6S;wltYdaUwlUC&gZlB*@3!yr}?hF_z?tYyM`CFSC3q^#Y`*0K2GU-4HuZ z;LDLuOZKmmA=7!i1gc!w2&_(uzv=JJMm2WVq?WZ)Dwc_Hsqx~~b1gM_q`EQzS$)*y zX!Yb+&8#RayPp8j|3m8VBe|LIt4wBI2iCC%)*5s)&9(i49a`RRelMWO!7E|4n~drw zr1xri8P%A2h#6LOM1enXpb_Pip6kHxA^9LmSya{PHmm!R(Oy*98re<neJ>dR>Lon* zD;Vfwzz_dx2V<7?LSHFya&iwcxv#xuOyn(QR+IYDAn*WdYM|1-)S!AlGkeGz%cSZ4 z1LZdO7=lJV=NAKvc!R7LdO5+o&&<HwBz!HBQ9qa4SHinWKfN)#&H!Ix%9*|RSf|x0 z#s2DS!~8H61lj3>|JB-d=lY3jC$;Mm^nBt~6qOsqxwDFS>Fv_{@h4H!=5oY@DeIvO ztCZQ>=57ty3B|&K?9EtHlwbG5qU7X?N8_oJePs>c_JUSN!4@n$%J=#f=$)PxAbt0B zOqP>?x^o657qcFbsGeG#$yXfrEVPABpi;j#<f<xrgE8tdM%>7{cdDY_+v}paFo`Yy z5(L>>z%x~4HaE^k6sjZpbseOeWQ|rH#g{GL4N*9xp=83~`*tD3=Z*<U&+x&qv&lO1 zOu^@a#{Fwj*^WZB6#(ZU5YW&0mb9y4+f4iBAGw~i4i^-#xf)9xUSSzfE1u9x7V*<J zKNb)>@07zWhg7QZ3>=&jr>##_2<SL<1RC>&y<Ae=3cI>h>1(JI_t9iX)S786Yur`o zEv`&AnrNTUyU#4*wO{O6`Nj0Lo+Vylp|0jy<;2cyB8WnB?lLme5IT|=5s^oXW_Y7H zPg$^bY+cjw+Oj#mo|$6bE{4g#SaK%Ol>001l%%xQ#BTu4w(4U)$*ZYkQYo*Am1okt zFk&^6b7uWlBkQFWrqHjSedD*Jm#Am-Tk&}Ons@TZngQhc1pxcjdXE?df?$yE>7^C7 z#Cr$l&u3qX)ZE}ABzdDk`28vSduwZxhmTH2?kLFZxWS~cGg)(2&_=py@2t;_vg(?e z3^(xMp3v@X!b=Fm3+o|hczH)bG5CAHbUXtbWp<B4Z&U&=jgZ&8YevIpk3nOuK{e9} zryru_ag@U)E!QFFE{@VuOzAiUW`axs03%qNK)5MBOa)0k0j35)7hJ1Mn;x&unn7<6 zAU1(%k?cPEN$^u^hP@to!?wOl1;xRJ2`O^QPMn4=TEfNvhA0f{@c94#fE(~(-@Vs< z9`mc6LobMjy25eKLOw-3GoHPv-V=R|vrRlIhS<41q+?>#%VJk*2G%%BAcF7ESqc*_ zzDo8cVc8V#N``2av!(ajiP#o8278$t*6~P&JMXAD^xhbgnuF?0XGfAJtZFXPt<nH$ zZvZZ@wSA|yVJt0{h{?-$&+DK=w2Q^&$!5kss$n(~O_Vo6nX}aog$;V&*EcE5CfT=z zC>LP}#;G_@#=(Rf?rqn1neV*Qp9Ok?7~=+S@7SDuM}tDzRFKk%u8R5^?S(13s}iwX z<vql2EYdpq?}d)=UbbuDBfWVq5<(-WyY}n7D8anOOq?T8gve_qk2I3AttmpNuPwL< zQ$Y_IfYU>jv3hCurp~n7H}Y|)D<&*I6-B0Eyb9Zl;+IJilGed?KXR_ER;8yj_<eX6 zlwQDu_g)DDfa%W+FXt7j)cx%*Sn)P0ynuSYmbC|7qGbF94KZtVVRwlNs+Cy;APZ?| z_p@@X{t%;T$_$9O@v*RN$S9}9UcB8mz}}AX-Hm3$;GU9SgHYp;<35%IjMPgPT;!bY zdUkyg)0(d4w<=0#(!D;jzklB-aO#L9FFj}O%VME$SqHhHYuxGygxKagAZ}nXNYCOb zI*7;5eC1Hd2iD7wWuJ3ra>{WS%*I_58l7j*LI=}u4W@Rv{N0<?&3Y2PUmZMm*&aPB zlGsu`Qu}F$G6TB`<Xi%~mixVZuW|5OEBqa55t0()0>ktW#L=XLhOPUbIRP9!(SBcL z%^dR)owsF{@p54j_5%E8t5|e&e!uPjwl5)$2@lBe4>-=C=_9#@dT#BmPPhsgSr?M3 zS}gH@bYNrw8_qn)46t815COXeDJ$$TS@ALo5)}$N7R)12mZLG!`BGL!@q}dHQqK>T zWk;0Sv`wi>S5t4lAFnJI%k=#-(r%=1%_fr*v*jjt6hgDZPYT^z_t~}GbgP13j7!B2 z^zkC|c(g}#aippNu<}!T2WjYHc>4K0)Y0^<9prVw{r38rcM*XQw$xM`<rnYJonS^_ z1b)#5fAw6(d6P)4^!J>^wl(AU64H_xiedg;I;j*RXqrlQg$hDnIM|Zjx=PAW(Aszy zvBV#%h9xERdCW9m`^wmGyNRP=eR5x$fC;u0Msk@H$MY$s4pH8keq_KKgx9Y8Oq(?E zx$y0*w?;)E$X5W4)|&wvJHsgx;Hc!&e`XHg!&*o9ii7+h032Mf0RNjFu)wG8?D@N2 z1iutqH-f03<f19?C?N+pVVMq>gHN>?5el6k3fI~OeKMm$v(wc(yPt4Qc+9%T@CM;e zIX?Y*mtL;;=r2&`d-9rL|Hfzly-lK%<gm#0QE0Vsk;&xxA==K2ro9?q@)T)Ew0VK@ zGaG<m()9<KjAU&}O-+Td6hg<s5zckayDD_Tv&s|?0u}_hTkp}B6d$2|qe<KeDCc|~ zzy>9J-w1%g`6r7JV3IimF79NlH*;-2Ap~#NKT^y8G03)E2r`eYs~1XJh~YKsU0o3u z)tm1!4z!KGRN!M|+ujv!FB>9u7-VjnKVwSuW7eJrMO8N3Js<l0LPj!41^YLR+^LU2 zZ|GpBTr|IiaL%x@vwoT{$ID-k&1CzXg^@ZcztK3Jj=(MR)?XmI{>*emiB-A+1gRH+ z%|&Y#xgXmY3bB{#3dz*Rt}RCCu&EG^q?t$U=o`4?r}S|X6$Ext?+F5B#rIbjkbEO} zoJ=)TGMsuZqcTJ$lYFEK+Pm){T{^{HrCTxPU@AKXzwsowDH?&Tpg*`E&NX3o3B%FX z_ekQsM}~IY*|LVDJcg?!G9G=|*p!#fX85paU>P&A;B2(!84U)_vd-q}6qzE-aQjiL zlsuiB9Q{S=hr4>X2$Q-z-}1T@2X!T`iqGKmg?d>0kynY!^h<kNPwOV`kSrI`r|sxC zpKDLf;>lrm%nis&tTNR<{(A1V^j<)03gdREzP&K%<~U;D<K;ve2Ki4V1FP599>CLt z95?C`!@C~_Q9NL!JFGw0Kc@ZUDjf$=HFB-`ro*Dtp@TdRjvP>B3yEUyB)Rl~QWz@+ zp!O`B{XrNNRB2He2(7`e_k-~dx#-~Q9nE1+TzACl=Y(bKPLJWdyN~135jyfo?$_3@ zYUOeJ=J=+Oa!b_I+ontlXANx0$;Q326@i}J&jL*!U{67{EWptqNYg;=Mf!`c53Ca0 zgeQ|R+&-7>J~;QyyW<`i*dD7)&AAYm(3n(}jjEzCYuy35k^uZ1II^rwS41nM_|CG& z=Wt6Sw^5J%U8Pj@rE;Y2Ju-EXYH?{JdfHhlG5x9_LiG`YS<O8giFJw-aoovfJa$Qd z{V5&PDGX1Pn&D!Kl71rLeLrPRru~9xl1{Q?*>7i8hH`&Q56_0XwAsp{ir*snNJa18 z28xbdm|?!-XB2|y)n`pH(CMYp<KxXv%gNc6uJ9Fwprkr5W9`(*vr&P$L)hk4^JUk( zHsf~z)VW139J;wk*JuSFv@_(`@($kf3k+F{x{e`Uifkyhi|9a!<-2`n$mzoCV0aEg zicav3`=%uvnanX#xa}_Z=E98Olhxsd;!_0<ShuZQPK0ynPJ3nB%bRP?I%RuRne?>~ z@GS1_g;{W+K7W!otJP#3N6+)&NS?}u9$xb3mB?~C4Oj1m#(-$DLE_%f>kA|9>Me-C zh56`OwxG8zp_H6_{Z}3NcKVc{VgOKRI5wqnw;fKeh(SaS6FF_=CP}1@7OW`;>Z`Zc z)H@xAc9R%f${pM=?omY&Lsq4Hh!wRQUF2;2C_)C`Ydo#DxsA!w-`3UB6D#^5!!fT_ z;;BOgZC+%byhV_02hfu|MCoyK?_P?{9+I3c@IHkd=l#0Hkn{MP&fM$4i!kK;jF4K$ ze2TRHbifUX=fgk$eiX!Q80tFHm+we}b&A4Z4Uhi<+gl6`GCyIaU^$vBBPXh-X{e(f z-@r-iYn?2{5L~@_tqiORX(myrd<7Op#0VcZyHO;}U<(An_79$ih0evb`Y3xkGlX1A zFwo0nPu)>Sw<;RHP5gefQU#ZIe^0wDusAfz^wrZ6&ZhppKGW0H_+S`NUjuKbj1}4m zh}SI8wf;b}rbef(!_acB<6hV~4b6(hKWJUt+i!iuKCGYJzu7(>r|xBP8@uLkIz76r z*H|)VD4$MDAs`ucXZIyCFoT%(E7N5<rTUt2Jpt7X2>ZLN^v&BZR`0Gin2I4{m7nML zgom}CW;|x{?nM2gkkh75!~6wEE#BhB2rvb@3b1Nl^!6*87F{a}y-iMf?Kj<<Gdw*} zD>l0RQAf;PnoH+s;jy074wyfL28XgIPz~a%tMTq$f#%Hf8#~1NV3OK+V8&IFB0B+j zu9a!ag-2}VVgt1M@5^bs)c6kDH9BE$Z~oeoOYt}ngcx!xGiTo4-9jA%PUll#JAG8j zbeb8B60-znM~mztV^(ulzXUD1i<%Ug^r=PhW~oHQP8hI^lMJ?^5g%Bn9rFIzSlZk3 zs~GMG1;GH)=&Uo=>(6~PGot=S#7r0yvWHB(N3HY0%C4h@-QcCOW6fs4+m_RTvuivY z1{KVY1nSzA)1M(Za}{|1@M@Eze<(~6_UibQol@N#r&ZSdHUUIb@|tuN`7G7+Ymn?5 z*r$_%$qGG`YUQZ-EjQsxxfcS36#FxQVxfTv;6X?&HbWeT6fuOo>LLuuIsEzPhs|@N zqoX~r?Lsz*umC6Mgm&CwIPpfw8vPeAD=zFFhC0*gepy)at{PoXJ_h4e#-B;oUn$g2 zweBaUQr_I!I^VQJCX;6s!Kq^x0g9s=P4WqkS><+s$c7&A1fO&kHKiyZlwm{RE&v;4 z6L~;Mrjy{r?V0QZV1`gG_z#T#u2k{AGoi+HTBY&3+m42k=h*l}A82!3i*Y~-ci4M$ zqj_`gC7L4VS7+A@_=?}Il`<7L47;;}$tBxhWkXtwwq7!{D|``D9C}3VKgmp)B{zjk zH<h$K@+981yTikdA#5P?B5<`SvFoC91c6u9K7~FW@YnSO+aY;Fd?%IbX>t7Y(~_X9 zfvoJC@h(C$vug>)yFsp$M}b7ox@hXaxT%&X7In=Rr*!iy^mC<HR=$PXlf?+!bX<c( z953U(fuo<1EIg$q;3bly)jZ2B)WHw!FYe4w+?KxYx9OqsNubM766uJkzd|T=iEn^X z%sy)wth~;3%an@HP2`WPzM542r_3>|90X7G8z4m(gXq1~>-%DDxh$D_#rMX{bxLPg zR}yq+oKhb98!zIJ)$XHdxN5<9UblEN+xzF$Ty=3~m0yHtH+J@BuYyU&)Q&;uvR@o> zmeu6&2nu;{;0nn>UGNmk*C?;s4>kLK39a~=D&qIczo{J~bM7ob<M>ns#BtcMrU0Q# zx;Xrs^}XmI+rHBH?GoRF3nMXmcnt{OxNCR+vXbNB?K++c?l&0*b7AAJxdm^FTKUfp zvsocF^is+_FZ+=T{7-N1?^h2y{$+<$!Y0MXH*no#v*IeBw-Hyv6EN5KBjtG8`tNWv zJ`!k(!QhHoQA;la$|6$thjgvy!V8vf<`<iIR<GeayB7s;<fJ<~SBpI-X_W0ARkO;V zzec-S!m6%!mBzxyWr)oMuxeP(SeeT}?o*A?wbNPfrL3JYBZ(f~Up!SfH?N*2g(Ai1 z?(XmHkjbr0$N$}VYZc^|Vk2C=cevM|YWM~OXp-Sa^2PxcH85pVA1C!LqEE$BQU5Hx z9EGX?Dkw%$D^(K6YyLGH=K&A`cJL>2zXrn9#mPVGH0z^q?$0{@PXPo%KZ6sg3m$(7 zAQ0p|0ju||e+nRAvRXhE->Aa^2=oR8^JTi_mxAC2?9%Y~_qxyjU!Sak$b<H$s|V@L z#BEPs=}pi3l5#$}n-*WST)(+G&*zqk;oXD=i6x1F14Wp8F};BG?ORuRM39^(74o@r zyp?8dBi{o_1Y`+7B1+=C7nYvY{g}0t=c~&hIkoa&0N>OItM|z)WmjFVxA^6&)9IZ$ zW6!9=d^CxF#Zt*!@WPh}M2$GCih%UZ6(oiludNF~iSZdx&GkltOY((;?3PebzM$A_ zwa-p>Hw1MhkN#p>2ms=Ob-o=|4cE0AHT`hg@dIwLrRvMNoVN+e50uF4k$EZ8Julw< z@gx2e<2M*OJ%bpaTBClCpdBpj{^G)|ovQ_3LZ$W`c*g3o1D*Tdr?)+V@PdyrbG<V4 zQ^VO+a@u25%=l7DF)1Zx#NzbrjgN8gGdT_7+}3)#zkDhvoMo+)B2V88`IPqllvsBi z@dGXLnUr3+)_ZHrof~f#qE#iXjZ$+j6Oz_Q9Pko4&j6;V?cThPa8T{3x$9n77bKE@ zVz&7LBR2t|sglvn5rdEj<bW4z1lSUA+083P_70|E{0d?Z`mt6zycrqZJ+G`tBZfMp zW>0p))>g>b`O2uE?LW+4;)Zue&Et-Pi^o)ebxoa^QV%AMaC02{#X%>aS-n%E^_FtC zXVG||pf24dWAS!pO_}IwhGW{=Tr8UH;Uy^v^KB-LbrNq$U#@IL6<aatV0GRvYhxY3 zgpems1!HGv4+5ohEy2fhi@`5a5LMp&tL*-%!W+}-`z?^O&_8m~kyh^g-y)JD0!$_0 zi;V?93>$EEtTXutf3-0>uM=>B`)}NjQ4w;=AT8bUk*m8pP_2+F?)T1VQ`c2jA2DeF zpIR9OR0Dsjp1lyOBE;<}-4vLA)slhFNgB9|?@i#BU+xsBwYTlf%I@Jfin~SfWng<k za|0ig)J`Z5<7!p-8kLnLb!{bcsz~{c`~~~F$dN*Rcy2q-6GGoX?a$_;Xk{HIe|6k> zj{SiulC7k<`q$#M=X4*$7J3=s6UA~NbU%=gft-pDeHxnPvw7<skSdS@_EZmw(;g<4 zkO-ylx)i@qLz_)=?vZ;_cgH)VY=xo-Nq_YMxF|?RwD04iRgmlyF+FqjlF8S)(Qtx4 zcDwCU8gg9pJCGtOhTk39f9j03+1OotD7vJOAXB5y1r%~JOQ<D*@$1*ah(g+<u<HC% zL#W<!om-+;G{<uU+yJToNUlMl@h5l!NusLwK+J$TFT=_}`gb7w^8TV2+y?zE7dsan zsJ>GpYxu*8k+dK&fjSSvX9JJkwmkOBUt)qL9%PXMW@cs+lKZ>6No*%xG4HQg>O{9= z<R0rhX(A_RSOFs|5+fW3PaIObau`}vAduZyo51w$7fT+}vUciDeli*GzM3}kUL?$m zF$B>J5=01^?bv4e7-MpXasI@2!4oWLqdALTR=w|eX)0*&EN9jNot(LpS@#S(&sWyT zQI7Ci!U&)Hzgy1d&Zc&`U3F!2A5T2?FZ2gBor~7W7gO|#bu^>}{iT_?K1=X%emSKO z1-8628)p(lfSm*?cydrijnm6CpwhZNA#c<h#3*<jdFY28Lz*x?xx(wH;_B3+*m0F= z+rRhoKwO_|wJr<WowRr?d5P`y)vqhRGQ!Rc&9(w7<`|1_^W22cB`LO#Yr~BotJoU{ zHxuNAp!L}Km`Dvu7<*eH!`y(G4ex+0w`_z1vXInrV(J@icW`Mr-2Od$x@_|?eb;t& z=YQS!CwKi{>pMWZ)7HQCGr7917C-#qRUWkka}b?a?zKhFWVtic6Fh`ee(kf}!U(G! z*j5*L;MR=Vlpu5Frlr}d9m1g&32FXay`IKXSvY0h@rG2NWZg4WDRwC#yI+b01S`<+ z`i_H`Wn(POzbA6tKwkFBwd)cz^4W;Nq>b5<Rh+@P>Tr9Bj*Z-4PlD7!h}TM{^W;)i zhmDZM(u$#MPBo?^ZiWITsSO5H%jRBGoQ4^}GLN@-F!06qz@GOa=2vV>Q4Z0EL!={g zUE*sl_^5lPCgf!~qcX&ARb*pSm%T6!a0WMa3oxU`D#v+u_usa@8KA7Xy{3t38`q_# zg?K2w0zQR7EvG{gK6~rGad~qEWF51>F+j!*lC~1Amb8V$dj5<}G7}vi5W+)Lwp@St zw#C@m&K6_&6M?5+fvjpTJGFrF<&pCF?+B628Jw7M%DFu5IHcn)VZ|Z3^_IHYlMk`p zOHYnW7XKJD96UgrGEgV$eB+#-I4d9>GT4)0)m?W#KA~!+r`FE&!Mz@0SGa?o#bC+~ z$bgVyj2yLE(+%HDl`2YpK8)F5MS}gwI>SNsMw&{NfWUu~@M=YRYGF&;lmzY-W3@q% zx^f2m3T1x3R15!vIxoV`^#A_g4V?98iNJJxJS>bU>{(X@v8SFRqqvR(c_CXi;*}8p zb;73^x3`HXla6)Q#D<)NJLQ-Nhf8xtD<QtOUV}R;t^ne+z^mS(tkMfuKz!f7Sb$w< z)M0_oQabvh`8N^t&c4#7B5dG-hlhdU>SQOpL;2-H2h)dWH8D*%<2%!ts69T|y(hMm zmJi6l#3ZLxS47~d+qT8{UF@2@P>5K@BzfXwYX)d7IN0|Ipo{swG`Ag$FD>o0cRd@; zlUnNZoS1-Y$sKmQ>U;nCh5O7r&EgXFhPT5{wS6V*TFOp7dEQ`JX>$vPgNOVet~d2R z9*mzVrVyi#6K^@I%Ywj8&)%=4vcB4$!ziE{D_mjLGjZGe)$Q#^g(THsNX2kv$Y7FQ zz&mFMCUWSrAliH^CJa$@RJJBOp2d^iDo-%x+q|pZofHeB^R#B3*eW(99Gr>(iQQuQ zwG4cI`$y}Q&7Sl*RQyoFD=T-}W%V`_N(*smrdlqHiKyw`3#nL*w^uCYQ#&>J!;gO! z^u&z$1)goIpZyW(Llr1RELfh7ufHEZefNTzxAO`o)jO&eI*362^d1WGrs2>x1q`?B z74_foeov#9()26}Nf*Sbu2x<xtM;UW=R36+9{HQOAcwRdOSi-HpbgotTuKzLO#4qn zh2-(!HRYREPJ;8tlwh&(GpL*^h@I6ntIbmk(PO($G=2w@W3^SAeQHV6d0?L4@` z_)o3gaQ&a@{zI_s99{J;Oksq|#2By24)&AkPJs#?Iw>&*FMkvi7wtVQo!_WndjjU4 ze!V8>+I~jJy=0F30Hv!>TG|e$rZ;Pg<|~Wfzb+=s)Ng?JbPdIMCyechZz=S5Qx&K^ z(%fF@t0!*THZMjsNG(iOdKs24Z$6k3{rGzBOAzqfdm-`r_|VxCAPg%i&<1pg@!Ve5 zx!&r3jZwp2Fk`ux7b=>%vv!MonED;h*5nt#Pov2?2pw!`|3<^SB3;cPD%UTxT7Sz1 z+#r+i$x>5e;;PFp_0&y3;ImI&yr8GAHiW-jjxDw|4?tu+*yQ!9GL@qT-wc#s_TM4z zpov}Ce(Qob+-}d(;_56b1+l&@SX1hy>)-ymHVAvohl&UPk0b<c4Vt3yz@Dd+;yMx- zPR=YSYG1Z3^8Xu*GFMktu7^$#2m~U$fwed6sg4vR3K_{c)S$9PED(A6qOw}&)g}#W z+d}Y{zw{ZeXnm_1cv=eDjX(kVrySIk8}JqxgQhC6yCCg7yA@eYhC7q~qIz(t#NlVD zB>ABBaq+A#d?#2G2gBwyY+ZjIp!LrGKT(Bv0JfE#;T5mLCgQl-&Cb<6m=mH!so%1y ziwG>Hc7i7=_ybVD3CqYa?LPnQ$M+_KkJfRnwcpN2bGY5`?$YzaE=wZ&@ZAI-0TT^; z_uL1o=zjO2?`iead?w7vyMy<T@^VZyI3Sfm&@BK`m0Ie*?tJm{NpIfQ6fcx4fbUT| z1OC8@NEl()a8cNlqKf^%zuB{lTC2RfZVpo#D0dA`{tD`@$1gb#_#0}LOFk^ZVYXkV z?ZB6teg<6uOw`(gVZPqddo|WF$<u|kf!KGi_Uk!`SVm;tOJ@Pl48SJH(JT&cQmr_9 z$z6gh^4wos?q8%0zSn<48~u-YrVq;2wG`U_S-O|ciDJu@HC=K1>MDi4kdt6E*fXUx zP)1_f`u!pmG<{I!AGsNKJ-M|bb|rg8^2Ykw#O+lJed~PAHNVj-2EO`@Tbr(xmOv-7 zx1hNQK^=NhV*BBU{Csf?D%&~x8h<hWaHW)r9IaA+Rug&p;ij%%=?r;1ABUyJAU^Pl zzaz|q1p@VUO5iq*RO0I=Yra)tHs}p@Hv`U-(d)fx4>(+Q4msQ<JH_pDSp5;a)q8T% zJ%gI*uxg@brM|KCW1i6DbKc=t)3f*w-?kr^e%SVGIeaptDiaq3V2T#-FvwHe$LhX> zB}Fi{HLAI4xBW&i>SGV5Orx=Wxt2WntrpiSuN9ZzhF<2GwWI`r+>c)z59{P@{Z@GB zq7eZ6oIG=!8LQL3uy3Ib-evy5m_5x8Gi$3~$Rxk~;hn3pS6<rDvU2FO7knb!6<<Z> z!_be#4LjBg?SgJbSn%rrRu7?97_eRjvih%+2^=39dPJgSYHul<R*_qmct|)>3juai ztLo|w9jaRmSd&7X@wtA%^|gQD=$PetdKwaofZ04{@R}3JbnDaY=;uyWy!e=t#UE$F zCONy7u3{6g?<A4y<@qzV>PF^;b-gL%{d04x2*Y$|OUJL={KfjHuOSHuJ*MYEbM2Bj zKRgpqP=KksHzD{C?C{>CK}`ZIZUTW+-lY9uJvVkue&~ukVJJIfv?d_H&u_~T<|>+a zm`(y`?FgqlTdT1eSlru_!vIz?9sF0*qWk2r>6lRpmGotb(m?^&8_rnNuhA}<<`Y0T zu>{Fs#`V7%RrWaE=zvsMu>~~3{M1Z4lSP%!v&XkSOt%WEop<;krmS4F#MeiAeCMB9 zs>Vau`Zgc-xMGJhu(!p6*O&%G>O(gkSDAwDNLX)%g*AW_uUO+1M?dhN4;bkIb>Lz^ zza`^go;_ybYrL+orq5g8Q>uke0ZTj!o6Z=&eQTm70@Ffj?drKk2BP`RgK79>&%`3R zNlvOBj>w#9m%{)@7Eb}hg&-%(*x4;1TCr%^(Y{sRF%wvfSU+f{O1h}_yPifpz4ly4 z#`B}%C2lI>O!tfgKSzdA_s0P~80s;k)Hp`Rwv{9YjRfx~aG0YG`PED8erWa%nDFGN ze)Ti`gQcWenStHWuXNnit2LkZYv>>du>@8CkAFkq|Km?a8iZ)a$-%P~sElCJ50#vj zm}YF8ZpF1PIFGVqhUn(T;!oM6lq^f5yE}cxMDHy)yK^G{M4d?&9E>{_<7<FkE`6QA zG<dTMzT+sK>^adxqCWbALE6pviWn)cpUm1<`e5D1<q;5M3;ux1T1ojLVY_#S2zrU_ zUBUGyLBEP;k@C9_#|D?{h+;>gdC#=;rswy>y@x?Wy?F`e-orrynq}}Nf4H<~Ibf9K z+Qt1;^2S{YegP4e^&mivXv9sAT4CMP-Q{Hn70%wGH2$chnan%l5e))-riJznT_Fut zjIkdIBXOo_7{X^%R=K>Go-K+TIFD~Yoz%_w>bnHY!42N#MR(mR)q1@k;p$W^{umfY zlhbkU1FE~s%~Du3rH}O#%egz+c37g9%gTrCg!&h|Vu<E7kQ+O~*LD^;5Gl?wu{N=Z z+9X$}IMtNo=haT%k?*t5i}$lOS2JkzCe+abbqyxg08Vi@%7DGSp}$>b0kL(HFzIA1 zCFiocK95WdSggd6sLj(7Co&YQWs0(q(ScL$D`jH9boUOhv+S1+Y=`{ehl9qmLW3-G zc+;!e=N&xnt@07;?(E(->Oy~h^nOh&1F*)F+=B9k07FgBdkNF2J8HZWD*5<F?KzJG z$^fbwhpf3Bf@(wbJMR&4XO6)lZK^;*{eJhtO1Q(P9MCQHcb%Gp^o8<i`#<_K_Q$|C z`CseL0AA2pdZ37Ogg(9VXA6zGkB*#OqR#`Teq%!}Z;9;eUl0S{>T+Vjg0L*~6^Is) zYfFlPZ=UFQ3fH#`j*MqSkr1&39WEbTS4UV+QoI6F7db#(@GScY{z<3$VqZ|>lNtV~ zi)(!mtg`M9hRtinI`OW21Z)BQT1C{gT~-7w@1PoV^K!*Z`y*+285IRz6RD}aB{9>a z8#Uu@Sdt5Q(zI>u%5EaF!{%9&cO{TL3Gk#-&6LiAmJ+#-ruiE?e)A?2xi^hbad|}E znh{a+8e`O?KWMzl&&7dGCZoxO_niCQ%e05@!UbhOL^*4Jc9Y|w#r(r-)MwYHNCd$c z70r`Iz74sQlC{}z+`N-1mDZN%({0Z;ZDl85BC*;Ab^xv6=jZooVsm8$)aQKDcz9BW z&4Kik>?*6rh4I=Y7zb8lW_dY~LkI{Z6(C3l{RPi6dldJIK$$~ZgeMow)8(b(=509I z!v$lTfj@5##P8e64H}L*U#=)JH<H!*R~rkEpxS|*`L&Et>e-&`lA*}uW49I!;6`>3 zF}$q-7^7PoLKTHLhtZ&yWAofUdJBQIaQs|1%!$DG56Jo`M60waJE*$+d{Ad$J}(_d zSJkh3QC7sm+tB*N?1-)*%Jnh}Fi&7ALU8`;dZ}WG+%$J=XTK_rovG5NPA+?^Fn-~Y z(K6tNt8MTdlJ8|iW*o0CYgs!-dW(<d;UM;fv|#Phe`p5MvpnpF!vO@v?H;`3AgL^k z^1Y`R96#-%`!U@TtG4>>bX(A>$JdY&ObKaQR~|H|4EUOZ)?=!JND$C1`dEFw+`7ff zkaU}8##VMLd^;dL+d+FKqgc1paX=nW&!;e3jMKRuAnWZReMNTZ%lYY<UxV&OIi&Jp z^)<(HOR=RoW;l4h?eBo-Ls~Ar+ne#Ex|5qI`s>UTojm8*c|G~Tu`O)++gLcFpfwS| z^dXbDlt328aL{z(2AWQONl&cb+V5JWB)ocDH|!(6@$MH*_4be()`#<?uJ9GS#i$nH zv<AE{rMNz*)dnk?e$r&#C8qft?m$tnFOYgtJ?=CFnos5-xs{oJI5pqk?kMRX)=ckH zK-EM6?k$1Gf31Q67bT#3uqO4`d(ZPUd%P(=nSForYEoaME{HOH+GodyKH++bPg}Qs zUHvy50%b*x{Z<C=#h4t}xe<c#fQPqSsD%`Rk;a?glN$xuIBe1BnD-d9bOl5D`jOX< z<oT}n`AYA9w)a_oAGHT-0rF4z(P#;scmwbfm)PVKC_p5%t|@#~F3+Z^n2LI@mBC~# z$S&BT+|tc(ri;AVR0m3l#D|PX4F{y$4_oYvstaAlL0cxs2->NkH`;5c6^{J(QVTOP z<65`8wBI;%^~GipW4M$1_dQ`@f}KYtQ8mARD10`=^(CT^lu)gQHJ#o!mW_R=l|e$n zX0`Y$5WDaN?&$$U(rkd$me6VAo^Ox#W`3^=x>uCpq^e1<cNUdUTxPb8<26RL7q?2< zDVb@bB*SY+d^mr2J1{^jm%pQarm}HhHsGzA-}r<T_uB=Qse$wJYxvv!zZ`^`>ZxE@ zP0^~q4xuH)BqkN^eaUObGh*j?>?sk+k_zpXPGUD?B|3j&Myp6PX$G|U7v&styGDbb zBRL`A+q^jo=*R+ZQb6+XnE&AHtPq7|u3uh{tD+`Ae4u1t*&y(Q#7l?gpNu2?bsCF7 zka?TYWn?awn6K$A#)vd!K;hOBJV}PR`DfuZGtAlpJ#79{@E@dtnpLE)rI9o9&+PMG z=D6q;y4%no2rvxv7{Oi2@c19SkOf%eqPrctW(k4wWjbP4-i{_G*;E;n69V1-EGMV} zgPGP79|mIkUy%a%YAEooNGn8-!ag6qoWAvI+Yr8^Cv``dm;WF<fNUZHoN@ibiyfPy zT_yGSgajaMdkgqjet-WdsD#8e2$%QX1O-D%BYXZ~>8ka-vfbZ8;+Mwrhmk2kXZvo+ z8EN)w8LpT*z@VT7TFQRk1Np(u&d%)B>AN3;H7_T$*5F8WjEZ8a)L0dyzX|AV0}Y;_ z7!d%!=oAooZayiJYXh`f&Qktrx9q!RbjnueU{g##v#Nb$)KID(T__vmzcwa#;`s0G zczXIfXDRP-E1;etCWx&bzw7RBLtW09u~qAD?F8oh>=fwS`tB0bkvA&)Kk5I^mO~?` zOU4J_DH!S^fUMi!JJremf0sfk{)&3Cpyv^S%RX{&I|KlXH=5QE)!)#69U5C+TN4YN zfVGDwi$oIFxmfNC1U02ot+J+wu;=MzbsSUIG+X)Zxb+(l4|FiCdI;JDo$?1SAf>RK zz<71>J+ry|khMu!sVAiANN{l7*eyfS<AT=?3d^}!%Gx#XYBMcCBW0@q6^+M{Wv1ue z#QYx4QaLvIm0|M)dGFJGi&s<oe%Xs}EN~B;c;sN)meY~##9M{#`H;DAD#`#fasJgI z@@JXBT{LzlG`%XgCgdf>JAG!`0j0YqBHCLyr<YlZ;D_J;0isRoK^eI%lp57fbA5G+ z^d%OlFGdbn@~L*GyWuB`FDuRF)WQ=^{v`usAZkFD{TmP4Lvr38quZRy`xn0J34oc< zoWw&X#(c;3#eEz=&B<INAw2ch7bDjexPT_+XN2^DO-L~YQ05AiRQ-y$u~V&hhLE7+ z*Pdm`^1i}VK6;o(YAANMKTu3BxLdqIieILJ(f;oW&q2-tW}!Q1_4}V5EMBXxNy*JF z!j*F8fzpCWPnJE<AF-tET5t(;^`K6|&(gH?1>2pr6>=ypn=QyZ??tAXevz~8_(9oC zR~V$@N%m)aTLwUxCu_Gr(KD?YHyu@i$<!Bp?yM+a+Q<Q>8oLd6Z>3h0GoJCwsgutI z-_5M7y%VFd1^uZRQ{N;!;L05Oci@3c*(#PCI48U)k<!e?cw8J_ha~8(LQkmm4A!g6 zA6MWWD=Ik}VCbKh!qhB(zyr{w`!e7~MqN*?>+BkXn&gvA$JNBkbT}eh0hxg*F2IbN z=5{;bnwl9Df_=tWImYr%-IA^V&&z{-kJ_V8cQl~3%78dcyaVrif8#U8nFPcuxF6_% z()>)&;AUqq{=ezXk#7^C4dg&lr%ft#eR63hYPYO?W#w75$s^gv-;@(;LXMc|h#0-8 z-Y@G_1RX^XnhSm}49x%sSK(b@ql<iudvW01g_!2*P`i$p7ltaW;Cfft*@Z_nKjwZ@ z8A#?df`j5kkg_fccLRv2lS|~yce<*sk|BoZ=?g(^NpM$qsBI{BPo9|hw1~mo>*h^0 zdH>pE?{%X#s_$FEi<VL*pyCvx5Ye1)rPK2`2ob42(D4&uQX4j<H`-r}|8g@<IG{** z@J#2-^j)uLB|o7q98vgX=9+y-ecP`uT^@uW0+0UixlcUM&OII;g%n3fvy|`Q7c{1V zGz}(HU*9q{PA_0?d!UKye^+<t_osEayWC1Gq354JyE<81=j$h4=i=FA5RF+m6=YsM zy704$1p#dQb)oo<0wO<c7iYJwC0&#uHgN@oz|e`vA&tmM-`p$c>KCVgE^yG8jXDUS z?W|kQhI_8N@pDL$okr`|*~=?9g9*fMBQr1X#=$ls{+_-@r8#wpNWZ098ms>jYCwP6 z!@)-%t*7QSMPt=c2brpuwL{n4&2puTxCYu4DsTbb&P(SZl+1*(1ONO>v-2z8@-_y4 zrM0*UUa&9=5kpKQA(3h+$6vGaG$pNvc)Sj6+TGnX&L_;6q%!?2v-|GMBm_V<{X;^H zG6Y}7vZq|_{9iT?1o>Ecwtq($bgbvFpoG7}xA%Vk-XKF)@qgSP!++weLl}X``E~{a zUIcFG5eXTTU~|{Snnia9wM3^mMCY#zoM>J8>ig7ImPoJ_WaP}9)iZ2<^qiPpR;puL z&ole&KN@WM51sIghF`cza!C&Rw0?=%?O(M?mRf-Dt$nZ3-X$RO?id!a;vW=o)irn) zfj174N=P_wMo!~dy$h&z9d%?!N@;)Jqg|A`Gn%}%4d+J(^$YOwdu@)IK}W(?M@T$T zCGPdBh=M?GI~e}?b?0yU$s)-o1(&a%oUHn0V6;M>?d{ACe{ow(&th96-R!H5gRs{u zXoWnO>JZ2-GrZCydCQaxqGeL-Mq(bD`t)rQ1|8>$)bcj&0%tn-cLBVL6H3!V3f3<; zh6qU`dnN2JoP&QH!>2PaFYL1UX#U+PBv=x6C~v4Iohy-*F>^HKgAlo<n{=M&W98C= z`#xj8)WVN;e}OP+&-s;aHD{TnR3D}Od~jgkVatvti}3yWQW$=CfzTK|B?b_(?UT>f z%B!gr7?MW_w-Nq>Ku(2wy02e52t%)a7G{qDuGzE8;o}iCmmbOoeVunhM7^A`RFks! zA;VQe@8S8!<y)6(8*LWC_&E5|Za!p<RlHRc-@7%P6WLZWW$_}H!HKts!H5(rWt8IK zAhK8fII5xW-7wN|b`&?s)?{uZzM$oN5CpU#Dw(@05lF-jGh^O%&tn|iMi{AxxRD&p zk5mUgKjsIH1k<I}_RX3rb*^ES$Y^2Zm?$y5Rz7U+>3|A-?7cJ>7}CCyxhl|Sy(fJI zX{}<Fcq{sRnk?4J6E<A-Pvj*1CjWc#Q6a9W0JN|a<+=#y8=Q5DrRcM6)I_dOYNmEi z>-yRBgIQ{I4tnUpk?~)Ji}Jtfsm?cG4i3iHQxJ{dQF|25%fLX>{1qsfEPs9i34HnU z;O9hnB>x(T{g>yiwq_Is&L!mJsL@m)9i6%wOQrAW(tIW>ya=NKz%sD!1@|--WbEwi zd&+hzv>qZxG);tKbQr(b<yHGvf7w@SeQ>ySAUVg&t96QV^y*+9QyHj(yP{xtCfv8C zu*|G|z5a>KDKpnH+bcUee7~b;cXDk%JdVk#H+_RO>I##QW<_SD)!TugZ+pL>mP#xH zeE6!~|2mk|=*PeY)T~;>V|cDu9a6hT4VPR*a@de*=hZ$olvH+Cxy&U~hqaENqKMqJ zM!B<d%p}KxtFcFp-zWW;sb~e!uj3%1y8dY0&rr=)I@e_KWTgD@+qb9jjjmpnYeo5_ zZ?+yL>$=|WgVI27)w6>4$lJbVJ)q-Jx{q>r>xkKT&0A*G{`2m?=<OYboXr7Yhicti z&E#vWE+pm7te1!r>&9}$f(KmipR$`yekRY3yjXgeUY4C05b+jlME@69c{aZ1_S>dy zQLIZdMxr-`^m|X!_m0U8CJy<e24ho?)JE19+$^tc^u_l4&accZoOkQ?Ot;HHx?Lr! zB%1o(&+8olBE+VRqlcBv{N^#{$Q6Y)9`2R^y~}>SA8k?3p_k2Dso^*{-`(V>c|`?{ z-8)Er%TF8zj}UGMKNtt5z#NKvPSyB*mmYfA2=bC+I({d*S7)21jBMkl$Sx`c`?(~$ ztyR1o_?@TD9)t7zbwF5e&~Uc!2RS$8i|&!Ks@bV8^8AVO{p-IMv$;(ghF59N6`l&` z=PxT;Sh7Npw{Y@FgG{ePKAjlU*xZu7S|=aOuJCF^64AD>ht0lI-XA;{H-*i~#eK9C zu5+h|4j8VsTsNxF+mQ2a#bi3_nUVbvFB*z<H_Cc%Akal5y9YkeSpr!>CFOmmRoA5{ z&>{|4`y!<!)!C@%m968Wr6zX+7lFFmlq&y5zDDC$1>5h-OjeBLLQV@f`gkO87WF+c z3R#lCl1-FNaJo20p8$uU^;bDgt0O7-T*Ae#f3?cq`g|&5+qX)xPTq%2!Ag!hY-?^* zw-?K}<J>D8gYg;ky=9f!vyS_gG|E$Eoi85adScyIne4YyvXjg3xbys*3#jjd+3(fd znvL&<n>c@tkl05YMqd{KZ(hkUUe7KY=<O*Jt5HnvEt}HU4sNW(k|t(1TX(G-_y_hf zWgHi7g?^-8ev0?8G<(o`%SE7KAw<u=dOaIgcsxvAS0bf8hau$}NzdO%{Yr(=%vptZ zB;7ENj;$JPaq*AkvCk}2*{}rPAXyhPj&;A*TR*Y{R9c$|(l#mswyk?KwG6;6&@n&4 z)`yFwjMBVn?VjibNxKmS1Pq7%_+t2KG-t4?2(!ZB7V^z2PuqcT)VumC+b)ZOnICfP zcKHOUa&~j;bDYz{KK2h*ixB0nk5ivMuGZG23(332QKs7NhrpQR%4v$rKVHI2GoO>~ z)!RMS=ymhZSTuM@1sdOfysgR;x)vZ4t<bx^eI7NWb3Z(R)95sDUHNg-cJ>Jt<Xo?A z>O|<rS4fk6y;T}-`SyFRQMkDhrjGTkKRg#QM82KP7oQ8+iXPQH?T1kg&78NeFWhaY z*2X&BE>-Ft@|&O~I{FooJUzJy@=4tu6IY&f#P1z{s1Kk~|F!8Qw~)PCP6)F2v10dV zzMuwG!LSf7i}odsNMwM!<5s+Pr{+*Bo7*swpNl3N)274Vv~82WuyseyO2MOqLE&)H z;z}<<CuGS&Y{XS}a6XZ8T9{+Qfx+Id$uZym483%=;9_zSp-k!hKF+O-<N9z;&2I(t z8`7^kBAbq*9pMsD*gVG{`4q3MO(SKxo&C+xcf)f=+wOTJoHR>o*kD73^pAm0_6k4x zKHA}(@G1=(4PNqQegmcLRXa~D+%`Uc<8EZN7cDZ`P|yzH>%%@idqHAycD@*V{|79@ z*8GJjy}kmI0{Y^z^u6v)O+y2&-!w}}v#1LO<nk+sek6Dk1Y{D8I#n0u`*urvrn)L0 zI=pw`bwB;mYpKan%a@nE8B)UPo<~`#7@$hq9vOYw%zym#gSvgbFSS_rO7E3Pa`)8w zuIXMS79-(bon7eWd(C5rsfkUY_cO8CVuUy4)T;@EV+E;$B}8>QG_(5s{4Vej5~84M zg)MZ4Z=qaMCN$G-GGF$v<<5tXCX>}hxf#Y0li!{p*~-2jrEne^`##js*l8N0g{Eos z*Ep`A?T36dp|mq)#jT@katCkLrsFevwv2q%!v6#K^g9B(A~Se?Cwq_9mwJoi4rv-; zQw_c#z_Y)DDd<Rm$A82?=FpvhKY@>w>H#8(^PA<YXT2vCGali~x<y`{RBA2l4st&! zV~X-oP0erhZo$yVX9%A$*G)I_P(aAN#xNKZ>9zHGGMYKjJ}gZ6F|wc^QI)uFAorui zJ3C({v~XR%O3Z`I5*B0BmGf%OPJ&Q2y3=Ag*}CXHB=d<mduko`KCh4ws*MJq3<)^u zWFvJ%GFdhHd0!3QUopN}W0-4Fl;70yDM(`dj@ZkFxMyM;4XiUUMQW*c<xop}0=5z+ za;I{d_uQRaIV^|~V^iO%lvVq3Cf#+Kj{R!XWnz7MHGs9u<Jas#ow<IUrt5$X#2q>T zy_x@gsB_P$f<W;OZ!_Uk4$yK+JJ~dhoc~?wjAlXGBeIp8ZL_V40avx<`%<5&X_}Hz zpOUDmk8#ybHKlvZG9T;pW@JcC4MD6PAgUxK0fRz^R8ZvT8hny31>Fvj6SwLVckEDJ zy<^=JCnK=Ffb_Gov1nZB+|w~d*R%?+n;Hc*IXbmyrDE!LzP)fACSuS1`BF(p#hn;L zzWK|$a!a{ZZX&OkTs_k;)vCC#!9VWGHVvOElG~}dP0U%Mp%B<D{CpPem0RZyBXSfR z7XY{ff=G-eG%vqg;_ElvD)L)#v^B(WHu%~&t*Wn7xqGjM#`Rn%iq~hfn0MT(YB7Da zdI#s|T;p-M1@B&xBug-J>l`6=2ls@8k<}nH8_b+C<I>fLWdq3XZ%JqDP{gV`TT0&s z)05x(I<@7v<Pu9)db<*IRK@R9XQ%MLs$O;v<_wM548EFt#nv$Z!{76Jwok}!$PJBA z;Z(M*UJ!Pl!P*incg3`%`f5hjJ6DzWDV*t_h?D1|bFjbi>sE2e>90hY(O}sN31?+k z&UUpqG&EwLo(<;^?s#BLDW2@jSsqmFR?T)Idmz*FGDd!9RS2JO)_I;4%f{bpYO+hK z+u$SVa`WoOa<+r4>q47YncbiSJFx%Mx=DK4b_PZ0NV3C^=;DSIQ}1Vz%BsgHh+|_t zTLKoAq5eT68t9=~2L-Zl**^|b3eFvT#h;S-Is&X49tWgRh;@T<2v7_Th`C*10dSg4 zsK?@ZYF6YbPXekrYFQ<5rY#Xqu#%gcO$z6B*Cq21?Cft_DE%tEjW86Ri^QR2>`Ylu zVkr#-mc#nF8Q!ubu@B04c~gP!oN7(T$>-ehD^%N+^d)q4&leWq_y=`Niac|%^^W-r z2Hl}j{VO5Lq?i-*+oFEA+RNgHPb-kZ_P-yqu(2n^a8g6HV4Vegs-vU(9XB2n)1yxA z*%i7s-*tbVn-MPVU47~fb61x_kCE+@MqSaESq9X3yz#n&PsZ&Z@gW(7mqoPh4=?n7 z_pgx1cH$2*j5*03?4)2gpgLeQ&{?L*6qY(>*n5Rdc!TXETh(b}5smh;8V`elRMjRw z7f!}9Ugk@XVl)pLLXUq&UD>FaV^&Id0NS)e<2aX&fP}!bFY?183H;+DL|z)K`vPmS zpUhy_Z-zVZ38o&iJ-Cs($k5zg{i16m{=W4)md%o4qkovVV`V)@w-&_%u4;5(KY+L2 zU}7g(apyO|YF)F?&9jkwGL4m<FXl}#nsgWk#}3oAw4z0K4mZz`hl`Vlg6*s}>9mE& z!QbD$PtifnmGe$@DC}TG${W$`bF6zqOiH_N<nS?vAcQs8x9LJX5#HZ4Jv4A1zyJQ# znWxCaFP5Go_Rh=C#S4>DSsQ@9pPUa`{@t*2bmv%!E|F{#zay%{l&&YLoc+h|vptPE z6c)D!5$tD(g~@cB4)pnKwP-Pqq#t2B-`Rgeo7sW4SYh_L+ApEKaxdphyFs7ZsOk&7 z$%LNLfhDIfDa@tB_ZGsW`M!<rSQ=g*v2K>hkDvBNPJbtc#^`x}Dy8^lZYD`N9QSjn zP%!gxV1jDl?r-#sRTIU%&B6KmYgy@Udpt&&QE6++!dV;qI4$oyHOuB0OM?nMRU^kB z{lPxQd?~|kiIEyXBW0R7O`5tWOAOAtud%XWVB~kFhKpjFO>?d#eCsQWNClkVRJ}{Z zJwcf#5X3YF4E-Td;AB2u)u1EDwyO^LIbuZLg15B)FZSL$tf_5XAC0~1vY~>2iim&| zsnT_+pwdJj2%#!PIud#dO9cx8g3_A`f)D~2Na#fnkQ!PD3011}8cKlVju~_<_de^K zvwzR|o%`JTJbV6ONoM98bIdWm@BQAd*%T8DcYUscYh_1uisD0V1$~8E%vwm5%sD$_ z#zMa~A9|UlG0Y+p&t|qrd7K+@QXn7=!Ad^ny()&i9)hbK5cWP8?EcVbD?!1#+G{PZ z*sy`9olGJl0`YKS_G*eHakgme*=AT?x82lv(+5h7<J*rbg`aY9Y530Be^MZei}7to z-|)EaCum)Ce70Ce(WnYAc{IvRNNLZ+`PIuefg3sTXQaj7S&K~LK<%ve&KV?j&hchJ z)&)($E|F1pX$#uCv+(c0pqzvZ%CdaZT}zHPquwMOnjI?0-NNBjaQs^k<Phj)e*HFW zX&*Q(!UX&Q+s-|302qA3r^|q56<ktiad*aYTOjE>PkdPinT&KFSHMD8d{g+ox4~Wu zGJ28bL$gwn)2QC@^x*|UzDR)jshOyL+2ll8DPw&)m{XzFl^qS+;z+kJodVbQJup+B zJ#A=V)m!_m*au{Ij*~K7LH6N{Ib;O)iK^U(5spprx}GuX5A^AJbIqZ!8)QT@fbhw^ zjVSVoXd?_$(B-A&vzf(<ZkA$fVH!>A^U%d%eRma5^femI0~%$f`EtO!6PvalZ=E`v zx@CrUjlpSrc~0SFJ+S1;o~?mW4M|nMO_N9wBVZ~LFRoQKf$BAoeC$gDGwU1rrzrJx zO-tT0je27ipIOHpcniCkTtK`x`8<tg6>p7JPx8msQ@8^oJ5k%YOt+Sz7(TKb3O;LY zuBSkBiZL`QM}qa27XC^awkBAi<<pY|!bst00Jc6zT;ULVjOg=gcf)rH){LcA>6<f- zS({%5DG<Tc71^jwz9CG~U;*K*w4${f6_b&1oHv`KNAze>cziHfz+AajBtV%Zdr|k( zjRx=H&q|(+EAvwzt*-}qLReOMbR<1*aISw%A-HrKI!@Z+{?qzE$)t-Y{e*dsVW?D2 z9;7Ec7F2~=C7pc|RXj%5`}L|nGzJ&88x|yJp9ESDWS_%ezlC;hov9biXz);)qkb0A zZAB|?9=?_g^N?``UtfL&<R<KGFI$3`=e5=lUf;CC^f$q$8f&kGr@xp9mqoirL<3XS zqYKP(+4nROwbyEN04KHN_&(kn6X%xF)nY)w$UEhF1pn@N)5DUHwv!92%`)G$gvfU* zx;r5}80643D8+eE;DFcGUziqH+5Y|BB~w>G5ecwhe=sJ0N2V}mal*#KW?IY}Wm>b+ zSx_1OPA9x3{3PpX7)%(r3ScnLTd%tbq!8{Ad$gWOk_vvXX(wR!L1GY~lvDD(mYg)a z3hx$`RpFD{*4|+4ljiC~TCG>S!M7)%DVnh&*eqkBaJ~E*KKck^i0@mmB;N8Vz{dIV zF~8qF<aH^b18%gau&3t8Ww5t?V}2|VxRplX^;Ls%fE>0nm?VwE72R9j#6tDpQs>+} z9YpIjIbtdUWSA<S0W1ov(BZMbRb;SKS!66jN>3`$oB2RQEMt;H<bJBSbKeFOu=oWU z6uo@BPpwkv5Cjum)-&&ZL_r)pp5#AJ3gF_uuuDx$hycql_Q=zxy~!UL9}BgtT)^1e zBwwRh;D!N>fSHqWGi!KfyZ>585Jvyu3x^0dAZi_$``BT!2*nkakeb|BXX67mF>3H0 zK4T+h(Cu;)1%zEAa}0Sd+r5;47pgGG$Fm{zaev6t4uIbvX$b2vepn7PcE~%w8;Ah2 zM-N?WNMaJNGFnK0+__u}4YcU@@UKBCb=h}sYP-K%?@WR1&d`p-?*yt4(uXkl&VEfl z*XDKO9yeK`nDe`UU^9U}rv<*wlD8AB9=!_Q9JAs>Q)X<bd@+ZD{0N<b!`_=zng|z< zpw<(;o}^>O@TDRgKu++HD8gb9F`FP!6Wk;>v|qS-g>z#zp`GTS=#vasP`34vZfL!L zWA%rt81@To2YqCGh1QohGQJpU=}sG&@3u54@W2nkWzz)t54+1d=qA6+rxonIgf(DK zJ1C)-Ky#012ep#6LNjWtE56zVSADB=XqNo!cU^Nqaie{2yIzdBsMeuB3AA^aWS|V8 z1oD?<(A;LFdjvA3RJ%gIxH=b^^uj2%w&_y1`wd|BAlwh@YfGM31D<-R{M)9-6Q#ME zDI!mU-dsBaJScY1-A;Ws8y(IEaJ}czZ@gW3HGKlFXRd{=LNPACF^R~=540OSoocPW zX(!+ic$~&kqKA<%@esIw1^7A0ZPo8zJ$$$yu~`DToF{XOp+AtCb%fq0)EOz%X(g0& zM%t&?x3A{AQG(Y3ZFEePb0e!@1*>2m1C5!HZt_4-a0`TINv&YQ_g4No;WM*q$sh{j z*2aDTH~6!J?Jvyf9HiVXeR+3a7$aY2x4LDjC6Y~BE?^RSoud|*jn&LCDY-wi@{AZx zzQvll0{GB<_6zP3CeRP}-`jl(ERhf~OZnmwMo3ARATKGJE<mb{<{#$`xL$6k&wmIx z7QR<_LOd3nZVE{^m{Qan#WGo@cv!A@xwz=0&s59unD)FbYq6d>uDeooXV2j*0CA+i z+f;(4rSH61dtrUIq@Yi)oMn%W$>5w<#0>Bh?1E&Oud6iU!)(AobJty__Sz8%C^QhF zo0%%#&?0(-=WgDt#r<!ENtzsTBeaA=>%pbnp;7^|TY*u!zaL;8*ri+1aq2vbD8rP; zn}!ZQ%;qK|TFY}VW3QccK9G(LSmxmH&0`hdS$&I_dnK;UKRyht=ot}tyVw_7e#i=F zb(b~L?Bv1Ui%e3rBdQ4O!Pq~Z!k~Tnf5KFQv;PjnY!K71GBc1QSv}CaJil^JFY@R| zcqD!0f_{5;2V7UZXxJro6oJfS6W7TV!<atAU@NT@GHr`l)$d~*EA!(s6%FBc0EcD} zNIzg_d7mE}oogdg_7HlFFxb;bW%r0_wakR)ZHo7D;yP3{dn~ohqC~PBZzhImvvE96 z`SfXMY!Zj{auV0>ZuW4#c^{MCj^4E{l4Xqe{4E?`6`qlnZ{N9TzZtY5V8*CPYli)N zghIqI&0KAvz3NX7v)XEJu^zFI!RDIDPA+p%?w>_o3EyKB_1v(?+GH|g`oXwCBg+Bd z{SX5W2Gl9}p~rwg*;B!Gxb#9sUSwiv@mZmw`-p(UJHpHg5WzWNsd%E~`=(}({C55& zk+PE;zq6n3nLv5gh}qUH^0!W-RFuyU)vUv=;B_w8<3Hkw87Ve$Eo_=mmF;NTFlu@+ z`&q<?mnq;HA7+!$){~AizdbDNEiEnWW#1MX!W2_|a%!HFsKWTw1fH#8FSfNd1=K7c zCTX)%x{tAV3bh{BV=<Za`Jt_LU2jm4TJP~P>opp6+^3YWI$b)we`{kU^Kr6Dzh3Vp zz8R;ecvD9=YX;FTDmW7;WQILzBsF(1U|_V*z)t?V;ZiZC6pQ&9o`ErHVF>&M{CN65 z4eYhe+;bVWd|^X#p#sFVB?u-IvdZPfV4r)`dYmzPB)Zv**ccWYFgd$453Ak(oRmGF z$4)hs6syOC(aF#9SuGMV#tr1qe0V>iAPo~_Yauk`P&W;px1=Q5l`2)?xF9NK1pCuQ zw!m9C#s^x*VW>J3j%?8ysfKR**<J>HsXCZ*k(F!phai8M;i<>ilS9ANd7u6T!$Af$ z4^mcvwe4Se9I9Oi&@aG?UR|(?IR?sq2-<Wo#nYR%I@}CA-2;jjPESwkY~Pa7KPTxw zy!-Z#(|^Fr;kBR2Vqz4OnhmZV0JjFS+EdS*RhYxUpD^%S&4x1Z<#%J^yS{5oSpy0J zNg(N$!ys`E!Rp}?rNY(Feg((hfuJAw=%3g$=<I*;D1lG@Zl7-Krhj3>>mW;eJ5llt z&>jYr1UuUML)|`Asy?u%^!ryUGksF!{XGDE)NM?2Sv)8ZGcbFD5$ov+;_+m$I1xf_ z+IVtif)G}rRV0La=$ux>Rw^cp_o}zqxOZCIN)^BveF988>HLPwxG*9UvDxQb-oU;v zs%gcpK>Q=BSol_Ld#8^*icKAhj)lp$S`^R?ID6{{Us~^4+schD-zt<$CfNZSp-+T) z8MB6=hJjtQ>md_f;!k_N&PA9Fw_EWmiL<)$d_fD4Fg={Fa6Kg?6G4C6l8P9f8*H@o z?#F^)ruiU2e!TG>_R<6GMTKSBqH7Q8mP$3k=2@4+?d~UTeryAy{Q5!3Dh$Q;(D5Cx zzBH9hK+DRtn}fQrQfj7CiPfB$yDSSW+Xf%s1D;VXh*a#8W@#lOr|qJ)^H@uZu&cTj zD&1XOd)&r!Or^u`S@{4~ybe<I`nRP2@LY`Tu*B0+2N&#=SmYa&EJVK&!lJB;4U%UE zeO+Y9zSk<!bf?j?Z-V6;^$yro-a~j(-^_~Xy(9rx#Ir=-6Vw;j=+M9p%N$udfW)FF zyzk^4{}pG$7z4RLTk1cD=%lsM>1q4<mq7YE?1OABpsaIIjP)fD$1u$-wBs@WHiB<w zrctRW1IU@Y<B<5ex=N?hspF)=#J)3U2oas*C!AXKwF#7Aj-D6^0L6P6(yYGd;yF@z z4$b%LK`;gU)cE%B+Bam_t|gI!3hPn=>EXKR?wKM)9M<`<HTe2UGHf$U(X^2hU&y!! zzJD1}vzvektA*mMQ*JJnC?S-vlip@Q2oR8TBmbHIyZoTN#wy-5x4&xf6zi%~>j<@| z8|}z+M{!gI=rp+&WwdwM6&D{xc82;K%HD;-3i9o_EXiQ(I1bA1aft#aknsDBO`Y$$ zE_>?UEfuBV+Ta+$4tvtcSb~M^_~&RYvwmBgbz}Il8`f{rS(vfdPeCC^V1SI@WtUSK z4?okpsMG+nTJ08=;JmR?o8kgfyZORt*iQMtQyd3!q+UQQIN>X#=#RGn^O+;K8pyF; z_MM!Tw`z4PItbxfLela4n(b@LogmKoSz8gFT1g*;Anvu}^m`8!eK%EU#WPSlg`j=C z5eu+R3v1jt*!jmZG0g;l3l=$qj1c>X)b^7$-jiW;GdXXJ>xI-Fa?`N`TUQtgkYRBm zDly^R%4XPcP3l?#^wUk}CU-sS%U=HZHDvPHNs4a%{L*pr8L(hAf8P2Z82k;z^{dRF zF{NHvie6D%kzSvc<U56g*_f)syX-wgX0lBSY8RyWH4XSNqIoO;X)@VM4_VP}cJi7g zH#Q+A%PP#O0QE`58DrDk2dxsO>1m7;^ONIl0xA)uwx{)I_7hK243?T7&8Cda?H8Bq ze{MQhCsK_8fH8?FIc3ggYG;BSZSYV*(p^mo*Qk#~>eMb7$Z+PTm{6Wfo>;N*NWd~< zD}6UHp%_OX|AM4BTF2m&QDc~bK*F7o&g_vP;VRo;DfeN)d3Ea^v;cTrOwa!JixKXq zh#Ml_ODqS{iqco|@L+n%nYhgbzJFJd&#O~$1}U*kDD8c@r3sswW}EsdxviCf{csT4 zPQL6(?u%7N7F#u4>MVBJ=NA>H19sEXVHOkVm?AexPs6h++o495Qc})c$N-PDH9sKy zU4F>Pf24q+)e0T|mxB$!74zPrdYD>9_!TphV3>a47<`YZU#mibUy5HKzE*@?ISsQz z(&A!#Rk*~NmpL5d763_R#oGCFY?e$|+;wkKzgpVs3^rNWk0MRZ#%n*lSaxMYxd@3w z%r({~q2ym<0tYQ+KE)&#wWigIcq`k@=TBGpEA?C2*vQ1^x2FW{vm@ObCvpekhV?Sf zHPw|pvfcI+K{?~8>&Ush6A}v`IND?q$9O&QX#9GhRZ7~K6P=2UlIS&F4wDmvd;9?q zM!PxIC&6Jlo8gBmEJ?%+sC;HS4eMdL`9Uqht=SC3HNN!W=(^4$tP!7F^`qo<-r9WM zDTBvddU#tmxsZAT5oLw&=Gx7U*%JE)QwtyO2IZR#bxt5T&{#&UsdTiX|B}s3@zvgg zhAzFA$+rPoz5KrT9^5Ab<05A^PUPT^i636E%r&${r&~-;o+7eSdL9M}*uF`{PtBqF zikYjmERVjv)C&~`k=ac*a*n5!cz_aYOPKsLm8<GU!z<f+ZZ=73tLb*$<3m+DE%t}Y z8%>B@%9WVA;cn^O$Hk<0e6Ot2sLG3sFqYSCqu1NXAKKBO7_$|ni)@|_PmDno*eUks zq}GV>Y3p$t2&PRUb~|i`RwK;#5-3bo>az|AHLhDi>1slYrQ70n6y9>jc)P2*-lxSm zg*n|c#rP|#<tKt_Hj<Pv>vjCx30N*w4vw*~Gg47bo+;>zhV$m;XlN(xEenY9fB7!z z`GJk)>JiUiL(-RB`m}0O{|G`rH*evos@J142w$0Mvg~~QO2rQMwaF%2V>^xC`(8cl z;ZK>$1Yb@)Kfo6g-n{Gw#m-h&J*NytPx~s1!0Ny1)2o{FH|^eVDgqv;EOL#JutBTA zwyew!R1eHT;cJCZnQ2Jnz+nFKR4Ua?wxpz_hkYlk?2j%+c~jTs?HgCnCNM@{UM^vW z3Dz)xklc9d5hwltPD;_g_`{!jaf9&$*ZkiHUEn7F*<Q~}UtO198d<j|&JlN`tv{d| z#pA+8@7}R3F0Kiv<C+dPJ2OOTFD(ws*Ondwu*`aSLq?ze0n6%lCrzs<V{vKdB(t<1 zpv+r2?cxsS%)Ee-_N5mq#hpOo+Yf?2V1gg(=@GhpV;>d>^`1rVtZ<rGx-Kzjbb4`! zfvjcQQ|mX1n6(-i)9v)2vb?~#YNV&-7Xw+Z{}`Ifyb>#sVvnP!+#B3O9c4!p^ON+D zM)gA<6$hrC7{>*AwBzIHQn~O|pJyYXWBX2qc$`6ica{M391O-qkt7uItr~fE`?xMe zvPlZsq+8VKeeM)$X&ikZ#{o!fFKG}E1}i&foy}NnFN(k+Ig7iUh@}g1pbjuZ29#|R zNX{PVF^ECh*GpwTycgw&Nj$v3eji4h>z*IoLE_^%GL``XcrqG}Tm~c7baq@>O-Px8 zk918pwxtA`tLoHkP1ux`2N#aFx%~c}bf6Cn-tIAYr8)qU6845LY~W?}`y!l$a1Y$j z!Gy!HvPpJiAGB7o&KEu^p@qz9^bcHm0Qt5FUzuBfaP0;_gnO8UtlvJp0;Jj{DW=u^ z4+tMpEqxBe>LAqvy51#W;qE1Z5n9%2jP#7K@F+@cJEg>+b=<L#1tFB1!D<3WI)gCC zNjfn9zvmU}cZcWuvMCn`EPA<)v#;iK(`@O_UO1KayEvombXbUnW@*Z4rv);czl0Vy z0=xejgihUpMO07JYnX>!gJ00BujcNqogA|+j=QWMCQUGPXXLkeDK!u=9VHR=I90m^ ztNS;f8WUV|dgQ)4cg>!Z@{p<D7xtlHQaic8R4}P;CwWTw?D{5{VHGr~7P)-$mp<Sn z%`>J^))5nSAJp>=(0Hedk`#k^mcUmnVoN2(?Bu%7pFZsGw3ffhk)L^hYc=P>;nb9Z zvjUt(<8QewQv{ZTV6aX|?)6<rdp;WIz9zNw;W>Q2Dn<}*7|x4)8<_rGv6|@RIcXTQ z_3#CE{ihRmkb}>pzoxOU$rKdvf5?o_kJbtFWVel2<%7YVIRLV#i~;bgJn?#}_vbfJ zC8HjlVxIII^|z|tm<Y3YRI>LS!CiV?GgHwr*YrjU?-fj}*b(>Nyvo<P8((r4DO>b9 zCA8CE)=Sc{&v~K=X%1kq+a?Gbfhw1sr40HiXg}ks6hhcB_e^z`Gu361Pj|PYGHmr6 zXB{O-*^WaCS#7A6J!Z}JqRTu4hfVvNAQjk#r0-h<?i5i|#z+zO2^zqMpDe9HDk&0n zzvt5)dW-1HzsnBi%!%kEDlX2AudalN+Z>yyn7}AqyzYY=PFG2aw`w4dh+*3wDmP}4 zKsd%Xu%(S3{Llbbt`hl6>>FP80Gs}HF|4TAz-+s4UXl&kd&Qlrykzo))?96|ENPw? znX50+Lz=H9c3m24@eASpU^P}$eCsyZ18)RE8m0;>J!-ji1?BU=Z5E}0CG*T-3-49r z0r9fP_z^}`tU}7VOUFaKcxCAvl;L8pKYD7YWKudqGJ`_M`4gT3{ONlz&Z{v&Dx^kH z(d7Z7D7_-HAYv6ip4XFSr2s0S)y^Ed3hH7DpA)^kWp5pWv1$8RM#ToKZU$v5fTr#$ z^x=T%hi)?d1*m&Z0b{$P9Gw22q3~(C65ce!fl7Ti^&H2~apVpTlb#>s3k2s&Ad8G2 zFwOP>pohBum`RO4_C`*1*Z5a%bHY)h*8_rFvN70d{baDBI`bKR@A9_+gM>JblID74 zzoWmU!g7i_Ngyr|j;t-%!?7n7I?Qe+VX!LFT1^@5lpMsv*2@LOlWw&fXu&@MPijGI z#)gW?>#pDVB_z3UE9<eo2-iasxU((r(G{*0-Q-Vjyk&4{r6ebi9gn^V`Gd|rki?ld z?<nWFN~0khKdk9Dw1(PXEKR6(j~y{pR64P6Ypqr1#fV3?4YrxVe5;PPnY?$%hKtSk z8gZ+)7jOg6vhf9`5xvDBPK>lUutVN46}Hf!dTK-^>+2O+qa;n3nQ|H`<At#NHI2B< z53~{BtRSXfTW|T|;iAECYW9}C?sLC!9mM>Fo2r_&&Ptx~T3es#QEWhKb=G>M7XVB7 zZXF}#M0CQNKe?L?`vfvT!13RQ%+dg_I5v(O=NO5<TiAc)w0380^!QF7$G$?c%vY5* z*9NL#&bk$yt6pCo$l;|{4}8jl?mNzmE`sTZ4v`adCoD2h9^+BZP=Ys&EPyvYNvJ%v zL%+eY#^!MHJ)(#%0tty{Hm0?p+H#hTk^J0!{A@?w*_QTx#Rg1R@dHU7sDi(cIW%e) zc${TQeF_276L}!T<N5j|;j99YJGVn_(?PR(O~1fsZXgl+3?Nio1}87jLf$Ott10Bc z@n_i$J_?eD##Sp?YiFMa3V?eeK!G_x$SO;n6_&j5%8-)KNI{_kZ(dVm9iB4Sd2PKE zeuo|M^~yMcRR^0m73awl<H+O9GNrHQWrvwm#-58$UC9TPy<46xNmv<vptOs5gmfSO z_6htZ%a5ThDyG28jJNtLFbh(n(9r(%C}nW=zsxCl6|JuKEYIf;T4t2#uh?LKQ#m;s z&_KkUbt1^gMvS&V>qj1}?3`T@Re)-5Z)O)3<N*z*aTI!CSvBiEC|Qotgvrghos+X} zZ}wzwCchw(2*=0?mQi0r$IfYWV(fGZiUT^2<|=aw*?DJ1_7+Y;7l3AH<}+*Rd_K3j z?wFT`ZjIKwmiF0)T^}tl?5*o&H-^HfM43ZystE*j3EjVI2wHY|g60{Ez!U`qa{vJ9 zlTIVg@M;t)XUK*kjS%MogxO;|jw6ji3r@0Ib`51o#E+>SK<lY9Vi9Oo3w)CFqeH1Y zSf~gA%mM@|d<0s?#cx_%mflfvm1Mq{5C|9IQy;H66Wh`na8YQxD6v%#{~(j?*kW8K z&s{|H=iZ@OZ^)wt3~-?E9DypC1{@`zcvD(kCsFQE3~@m=1-s4fA8Xm?LpRBjaD|l_ z`K;5pR~c6dGRKW#itOr-9*+8LIP`Uulamk5Ye{?MGp@E%r~nPt7T{#3V7`o%pWKZx zZY*hLNkM%G)0om5;YTo!EhT0=N{9(7(MZ0~zP{Jj=JGwFo+WbDgLP?>R_>X(vcbys z)?2j}^Nmy!XN*XECG$<me|65d?zf*HW^})ilk>NXvxSY`)fF;#=EJ6Z`Zk|@_2*WH zSeHc6kply6Ym;175YzS+R7dtV@3;3gSrPiJ%=ZVhR|MYQms3BnztI6$1k}n5Xb6av z0MVPm=X79@5c}b?1L=T^fNllYe|2fvm083Vmc<6u6Z}PZL(>JDC|eiWi}BcV7f9#> zJIlE9w=u=%Ps!^W3!pzZeD?_de-ZsNia;)wGZV&tq`Q~)wuTahbXTnW$RLCuP1Rzb zHtCj5Y(SPicR<$5cQ)RFjaG6YLm{p@Vd*T-NDNj&P@GH^^my_h1Fr9N{fEAUVeI_m zRy*fdV?p(};oj^gtNO-)r_fZb$FX|q<7EDe#md~ejG{bhvDVUbD&$RsJp-?B<{~SJ zo~s;wjH*QOsO5`I+ifUfv^|P=Qblk&a*B}jxr@G6$8=9??l4~sZ3I4EVTIJi&EhCb zWal0__1T4?k_jRQp|L1|goK&Y{l$VZj@tBle~clB(Z_ZiJwrRxH1z$(fZ$W@&u?6B zya_YK=pgD1uf6B1yJnSPcOwavOgq4u1c|NhfSzRTGr8%fl=vrsnTEw>sD}mb#^x$J zkFX?qtThYbKiWsrtF%{Er-Ce$Dxa$K7bbeEU(OHL2M8GE;0U%v*Pp2E^NyX#l>>h2 z{EoJsE|L|^vt9eY-+{b%AoK{_X}ONcgR1k3grUU$=)CCNpx-)q^FG#ZlzXLBFTgfV zvl@Bi+^QWl$4<)oHjbh`Y65=g+YP+nbSO)glxZ{_^l00tIECD*ucP{f)6&etKq3ww za}<F<;xNzt+;DJ%Q@!6S5DyD4OGNqL;Yq`lB1%iytI(eDJuE`nbk*}5l@-|9zBBn) z{$5wv$YAsd!zw5B|FG9|sLP#7ZA{e@v=?<z?Db;+pHP3mwhwN&FhoTNFk>gMQ2;DN zPSZSKd1tqjfxEmc1Aq&Z5%Im4zj^0h7BJX-xtt0hBqkVC@+p=1Z8_m9uEx`#)Qgdr zE@2QEo|+N18{)A5fY=LQwwJfJ97iyqS;4l<oG;qhZz(8b1f3+uatY!Df#3EaW6xD| z&*pGIOKvIOlO(m!*-PqESL(YLwO|}?DB12IctK&ancSoZBD{=E>eQdQOL2HV>}%A) zXF7bD0VsNkX~7#h@11jZkS=lbd5l3uH6eM4_h;4CGtiTBmBn6(ZcPY(6G2eVtW&1j zH^{)w>~Jrr6?BCy9QBWQc#;`S2|eq}2}t({7g+tS5XL=JXf2omyJf_=z<7rp9spf# z01peChrX`0!}U>~xipJH6<ws%wkFChcNVS*h`9v?)bt<MH0k@-pD+y`Q$1#WjBY_{ z6besmFY5594jn7r7UI!o5X(fR%n0efkC^^nR?Lw=G1KQQGcM!GwVVMm9n&M;!g2>( zf!{yRrk8FzIrp^?y^(Z;*<%AewZl!O2s-*V4j!zC*^0#<sdvfn6L)o!SxwG*%VOdc zJ9;wm4ET5@XTqSePM|Uc*z6Z;Cs4w!u^$>A+nSL`DHXeN%_#*3JG%19@5#y}uhzk8 z3wP9d9<giq;{_IFhm%j2$aOQS?9!WbJ7cYiN@kd|$>hSB-C2D_fh{+aT5IDL?cEc} zFO=Du(5kjXsC;c+pZg_>Nd5$ul5WYXGtm|vVn1ZYtvil%y^$pJNCViv2fF@fzKbq4 z0E1#`>OSe@CpOjGj8r#~-1;^6;V*$=OF<f{wiwXA>fMd9K=j-a>&qy5EUR8Dd315< zu9|px<)(NijPZEv=fC3UU^8l9gGy6}W))_wX21H@8de<m>?U31#_?Rh+LqI#-wdc~ z=h9x_Ug_P?Q`0~^EFbUIB?XOI4@YOH1s}HmemI+<j=0k^^a6n$Ay+Ps&P`QtarEeq z2k_4+Lg8>sw+k4zujF!@){%*RWcDYnn3w`NM4rnWE&Z<Z6dmy0R^vl2FB4~y{fHi{ zpTc5{B;;~yLO25IJ$jFsuwEqxB9%e38(VxTo_aoh$8AB&YJIz77Pmo`D6>GiwFim5 z`S`2(U!4bi<!7$$u|TgF#O@ZfobrDOysM=kE-tI}uN}DvMJo6GR=qw_g^F2z00tX7 z1-*A)Ylux#>DVWHfw2u-m;dsHIo7qQ?7P<{nEsvn&z6|lel_efIK2$<!~2i{m1sEs zXG|c(V<qsYqUDTqB9fAGTNFn4gz7G+wJ!iNtMjOqL|X>1Ub_jiI|r<B_cJoI>ADyJ zPXoJALxe{6N0%o^gXU)V?P@+Jh#>?#Az%w3o)9F1U)=UvRxp$PPL>@;K3I=``H4_0 z$X{cqE>74-Ds{vlrgJoO8$x={E8_>EZYiF5nT|V-1WRE51?zaU#VY*GMJ10CkUGUo zX(EV!o&t0uh^}0RqW55ZL?C@vBSj)ZtfP))XS^08M|0n0qh4!&k*m#OZGT-h9!E`z z^K!zvWk!<Py<&@5^~6O!oo``leTd+wM^jkak&OvZOeGY5xcgM!_4v`cJ}n;fT)Ae0 zH+c|eEl0mJnIqtRxY<eFs8zzbjpEZ|#t&zAwgwqQHomq6TL$W@znzGj2L^-hXP}8X z8t!>WUP@6ts~OAkOue`zZ%pCis?~TgHfPAWe<-Za`wCnpg}=%SVRtySy|rVpPa_vJ zMJq4CORKmuEYF;~<pHT7VEGm4tws;&H13-3U$NL<OAOMV@3K)NhN7!P`^D|;(ZO|) z!_fCSAia(~H|0Yk8+3SHSrTxEboqPWru_K&^||L#UAUTsfhs+g>enur`49Kj3rt^v zcVgY2K7w3=AdC~d8og+wzKkZLU(ZrPbopb4RYOP;D1f2Ouo)k(c<WfmYSu!2O|iyM z9(Rh;LoheC#3c9LjEMN#>`!CU%ozG+weMk~Wez5VCvT9QyJR?`s)=j2I17%diKLj3 zprpOOV!;rTbG^?7=t7Qxj3KY@aIcNzPjRTx26X&q94+|jzqe$;Nq@QOe}w0`xRmyC z1}hB^MglBN;BWOzXd?r&=Oey!>gk6PMM-d$Z)txbI@BS~W586*fsE9?JHvNoh6-E9 zEq*TzSpl?RSX7;>dSxyCjB;%xTTJ$Y2q%{lWBgEZenAvSKJguYV6@tM+pvw(a-7%N zI*qSoAq_oDO73f&u|sV?0PqZAQn6K#FSnSYFGa)V!Ns$z8i@E7RJLji!de^DTAR^@ zO#d=7c8_hev=dLxXzo>YUu5TsE!_0pW8}*1d^;-LH=UaA$)4t_BX-ZO>-xbHRS()) zT_b=%h>e2Y?e><39~k;_pF=Ix+%u?^XP5g6uXwjENP5`Zzk#+3jr2VKyPo5$`6KL% zD3x<B!2j|A(9f!{kxD%p)Pm&*9LK@@iS;KJr?GI;E`T}Yqb<Pq4(zjg*0OW#tHmxM zRWsw-les9~w)y<`hyz>uofoySe37G=vEc;Mk6<7YOd~qtPTUcn=m~DsRW-Cz5(%vx zrqi0@K3K&!S}rndd_xz}8v3;z6HPBEK24t7tcgR$m4YZH%0hpDBW4i}CP4{V$bS`C zEeTN>CTda|^ujZv1FfntTw9r7f*HPB##pumazLjadR=ALkC%a+!3;+Q|7F_JWe)mW zfZiHG0s0EEah{BE1t;^!$@ku>lQoJ^enhnZxy&gjc;~G;m4oKi4VA4dnfb*AL>!AJ zjwX%f!G8FRIlpw>v{a|?eIn+%g^WlY?u=&&<v#lvgr1#!@0Nzf_IafDrCcFavquN< zaWnJIx1V_Lm-AsQe%Kh<OAmzq-$(-G1<&{rz2=VRejPc?&VsrT!98-OevCZMa|>YD z$uzs`R3-aDkYo=M1^+P#)cpS-3G~7LGzpXhc~t9IvOnZf!kR%6s34RCs;-F`Bbybr z0~ySYiYiUVTrcE|s-BE14yu3c_F3vQRw&Kvj8sJTQYAmgdLVXnJXYdFvk~TryVZ}* zkC!$ZqTtUtHIV3PnGuj}$Hr#R^$*PUYKhqys#ZkO(1102&e_SFA^Ntyc_5B`89M7% zN<5Rz1H`Iz1hR%&vI51mR1FI7Y^(h>?N)1s-BV$<ag49}M+nF`t3tu1`IswW*8v7) z)&=-b+;}K+&5Md59{Uy)Gmjk@Iefo_eI*dDJZ=^>_e^?9Q@GK!HqE42duYHVb>%HX z>H6O$hC*e+A3WDTkwYS09h!bWXVJkg6f8HD_VGqTh(O>1Au;d1xAv1j+@ckl@K9;E z3Ma_mr)`r<Fz1%8?Q)^)u~_xGUbLinV)nUC%wpwQkA2P^qwx@~wAJH?3#d=iZzd5M zldr^FdoNwZBS0Aoj-DFafs}=Ax0<&Qfqwi6*xK|^!*!>C^))+-{vU~<0;LXySq5y@ zL5xWK)of%Pq3y9xf62tx2}A3Py0>l3GSb{yl{~!(l4HE9`H7gml1n2aXhIr`t873| zK~Tbe&V%!vrOhrAi(@>qZxd;odwD&*WyHo35U#5iTZ?J@+g2Siw~WfVd%<=>;iciu zjGbQV>ebb~`>o7+IT?r?*M@L<0@^*Jv1)E$|6@(|s7Yf(q-k;nWxf-6XV&{+JV7VH z#TGeT(s#F8?$h$~i#yl?ZAj~cwle`Z+pZ^7s#1lk>C<ln{)wTtEES`_hKE0I)5J)v z#wxZ;+tr*{WQAn{%E?zlE7Pe^996U6E+(Yd`LXLoAT>#$o+7>@*Lt>kkg~J0LG_QY z((myKkFz7Wlxw5WW-Oh%t5AVlqPF)uhcrKi#Agcf8b!$Gjx3Fh;B1R$=d}Yd1Dg2* zC6}g_Q_nT3am*XeIz2e4fb0}^?YXPp;(CqB?mWU!%NJL892h_C&}HFX?M-=jO`9Jz zbmCN}5OI=k3AD~03cYZQQy=873N3RUgr)Qki~BEP7dGiDE^10G?;1k{v^`z?R;QL7 zRR1!*G!nho!DC0_sam`BbdgX)uo-d1i!N%fp18#GKTi)m@!zF~hW$G|^xx^B|4tA6 zcY5f*(?kEA9{T^c^w8zf#VLV0RZzI`qqm}m7V%u6>W~DtZNE=eh4$IgPxe+RB7IEr zvU1L5UFA~-E=X{wF(YQcKVp9tBf4~&0RHPMc}RY%TUWZQ+#wE?x}+Tm<OSI-QEx8; z@>O6mZe(^9U)!~`a3dN@CbjIY+kZgbVB(uU<X~(7fCzRu1v?Iap>HcNG(jcY&{>eu zg`EG*7(|T-kxI+Go!@g!53hUP-~o*w24*i690T<{%Z0u>H83=w3hx9N<<bP?Dm}M2 z=*&}v#xPy4&3}|?76p$Y00lD*XyFBeUTxp~Kig9GZF%Xw*l^z;zi)pv)Ibn)#asfl z*Nq`-o0&>F5HJ@mBW^avww@>Oyw5RTmg4}_$U1JGU&dg*6b@CJ+!9Od`aSBQ(y1Sf zC$f!{m|?3ws^AArfgT^|6U-(Wn`k*JieoUZ-KC5zPB-XJ<8{GfFMI|5H?>sZFP??n zvS50@2mUN}3_5683<2vc33RR{GlHOax|6&yf<^SO@DoNUO1rPT->lJX^Jz{|+cso` zVx@Wbv_SUajdz40PJYiD2Yh^d{7sf=H0c5^&=QF`ou3{C-MyrlE)XNTb~K3li9*n{ zzfg+^n<B^NeJP@;qb7REb2pCgbdHFvmL8AV58|>-j?02ZpWmVW7qH8P+WfUC<@fER z5ucLl;W+HWa&VvH_~Yz1>n?EU)>D)!t<K~c?31VDjS!lPLA*dD<d@945VMg*N>`{T z<*QITHd3=kM6&0%#g%~!sZ0w3C(QRbbY9bYThAywW`2)ZdFoOCZc#aIT9O21k$Rc@ zsAB*2R?bdiW)>-FaGW3XH_Bw)6{(rMt?64jv|?^CySBURkhgRRPPWFwYVDR^%Rjor zr-?MxJ|OftJ6iHNSYRXfAzwjpUE_G^U`w?%a%xl&l#DK%Rr5%W$%*m)Zs!vC`^t?= zIF$AQYe2mF?q7+E%viBM4V9oISNOz?czwak&K&%;ZH(`}37S`T9Mk}O<j*WpX5D>o zr#@z@d+?94UCb;}8z_r3#~alUvSdGgXK8P7j*62hi35<`hr#b*Ss#SSawQp3b97s? zE$wff2Tf4G&N*cYzJdjbMNG$^tBeRB9s{N0c*PYyOzcTr%c)<`^8wKrhE>oxMU=>W zrAM+C5!|&)*8DPuZu3sGv{ekpgRgX%iyAiS1ErB778S-q1$;rg2@msQVLy;YD&X6b zCIE)azBc_G1n!jWy3R}0o(}RyiRb2NBU%;Z$QY1Dnxte!14Feb-;5|Q50qj~45A>> zoB2ecb@T`$i(oM7^A7*eArl7G@e~@U+iqWJbn|DCRuD{QxTbR$ES0~+2s8`eaQJHi zeb@mF3%m4q^qb>1&EYCgwNJBh2J`&}<=XOn3CBg}HaP8Mk(eV<N@pRfD>tXVtwI$V zU>u-wLAERZ$U2y%8xqd(=JScZwjrJM)T}0_#V%%qggbN1bcc!dvF$$my;+tv!u8Z; zEEvjAvjJ`Lz+KDw{T0G+R{ktj6uk?YWP<;Ebk+89K3ftXwsu0yim%SILuB#JxeMEC zZt+k!OSauM!%X0TwR~9=dXyP5O9Eff^Wh!y?MowOY}}v{5D!z%75W@%UyU<YApHj3 zT|GDxmZQ9sd0=FKG@W0Hhij#;J?j>8WVH~S<9Lt9j?ioA;Em`;SzjfoNHR-cbG~!0 zV>b@ksE)eP*?J~uO%m)Sx0VfI0j`-P_aEnz8A{Ib<UkOcQADsxbp>a&YszC2>i4hQ z?pg*~$-^sUmQgtbQ1$SsbtC!;{;6Mk%6QSuaj-?VKo<iW+FP*hT$A;o+2&`z>w!el zgvrYuEads<Ad6M}@%+zSRCiV8*-#n#GAw8o)DV-m_4)LKTLqr|d@j{=u*n}JkokH5 zCJRvSG1z$!P&qpMyLiQMvcU89aI$k!Qu0&qRVDZyrsbhq;BME?pm6UL_uCV&cR%?_ z%DH@@X&@<~(o&$UbB%oH61G|58rfnp*;X!fMWa}#!wUGsXh3j)OyD1xqy(o9C|<{g zdC_#1#zcY|lt~(FhE?wsn8<C#kFV>aYJ=A>Qkl`B-c@4To4n${AnS(ineQ_Y%?JI( zrx>y7^Wid0M}G)<P-7QtmVp%ouxDP;dYjpy+reOXNLWJ0FG>>ns7%nsTiAY4*M*?a zCpdvT-FDaJwdmY!c@QoZ4AwWSqb@+RGe%5u8*kF^Q<G=@l9ZRK$H9dA#(~n3V2zwr ziB`|dMETkKDYfXeCRk!V=8LK6r6+d=;H+pT3$||Ai`d5lu5%C?ma&kgp-jEgQ)Ev? z&Ge|#a(?P8S$AH8RgR6PbE=<LD`VH)38X3#jLM%miH0rduF-`;Dn7lkmOU(4<{l-y zpuWM(#+M;ID66%52NJb6HzUXc)2Mc^JvRf!5L8GIot)Ry&6~OZtxuy|Ah@cSo^p*b zlc}6#5d!6RmZ_zKlYEPxkXIb$6Gojc9e*W%P*VC(u{itQ&RTh0S8WgPPYQncc8O^3 zNN~NZqoua3;*4)wAz@MUved5VsL_oLVF5jqZy-(pOcxAq2L6C`L_*uNXv=|3kOYIA z)X-nx;9*Kj@Q+_!05n)|Tsr+9w*&P2;3(U*E?oe9dszuU3*o)3<Fl1cXZc>yBljJr zU)p=s!&J~w@6@FF-HUAQ8Sup;!-hIlHSt<k$EhQRpqXHTHck+wkh$<k$*cu=b5&Ny z+7^WkNtD-W*PA#{*0XUFA#CLC1T4B0LEifCylS(dV@>;cM~M$Iq}-hRN>RR8H#5|3 zp2Ciid}P8n5;0EZLR%db^Lk{>MIh>ViVs_vl}3R8usx^1DEp4`Ar~S{Sy0m73X(C+ z`h&HxHWCjx747OK8{<YrFV=zl1k3LWeV*p%rM!Eq?zwcBTsGuVg<Wdl&`h#6cMxLv zTB3cIyD9w9fjw^?+n810DcgUyvJwcdiLdlo*G;F^s{i&jo*7zHX5!L7&$RMZ>GRKC z9p?&OEl$@<eudXQY?>Bk5OMqC@vsDI^hq9D?`1Rwo)3DxMf1ZC=VKJa<!qK&v%)|j zQ#V<FgNnGAvtM>GsGCF1)?0AY>t_7crne&6292lGUpHh|Crq^5i_LF8hOqn?7TD@g zxj3$Vy5yqo)voC!a1D?kmMF7%nz?~tGrKkJiN&B2u#*}rCARkAzYj*op~_#*YgvE7 zNKgSyCZwQQjG@Xo_IoB&QkFyM_Wd9l0<=!<-s8r_aZQaB6lb%!Ok+cjGtQMC@pAK` zIZ?0-OU!v2t#h`;SqHuF_rBf8r_D^y!&>&-;k2mGv$eQb+zB5S$=-e1({%QN6<oA! zfhSO(+}@uXw4Ss@SV2J{x6{^xlyW(DqtNZ2)yn1T(i+_3)2VhC`=J$jp1s$L{G-P~ zsSi4hHYe5c6EgbVoyXI89(eP|$hsN7j(2zi5<o54VGA`s8a*?sdz0U>y+!yiQV@{% zgf;Eib;?&0v?uDZ%LVaBwT)$ni|c_IKUzm`;L|V*SXnHCsYSs)5m;Ya+gmY1r8+w) zZ6ICn;cJkES0U`SDD;x49Uyi45KOn{CVS8{3_AL<$@4p~&~^rge5A!%`AKL?g5wv2 z1L;F>{Li=IzjC3b%tR>UpA8gouMk$rtUlHn^6@h5zJ&4efbibYko>Qff2al}$<>!= z%i}5!X9`6L+~!0b7`Tq0UICJ+22uunTJI-NH0j!IBl@|8J*nSP@7*;Q>}8iYf-510 z(9oZ5mdH$2@gwYCuOER@5x)mQi0M*r?MZLFi*ap6t?lPu$og3+OQztWTiZ>R1W`)z z?;n2yp`7pM3kDnII`xm>liRy=lS23hp4{gdLSHO4TvY}019jm9VDXswr`#913jC$E zBT+f<iUo$)Hica2cbNMF;}bOBkJNnPaWe6!pPubQzRap4rITR$_`2Q)zw~|G$rXj* z6s9~nS9^tkk#&<_O(5b`Q6`FOuMH?xGKmX%s;KrhX1ZuPBzhdotJQ`Y8v_!0qGhm} ziwbCSyeFkX(qcD|pv*V!JAd9rMzcL@U!#7jcxUsGJ8PNs^kCL_l&~)K(jT-)B>GJJ zOK_#)Pe6wFYTnF!9^A7#Sjc>=4x^Hpt$IvPD1FNfYqQ{_VJl*6cN*`!AF}jp3X5%~ zk-T3tp3<MR&YN?W6Ck~wSietB4HO4xWmd#49NeZv-MZNKvk?n4Ei;@9N#MX0g$ft> zGM3zACqyAIDg~;Y!yNMU1wlXph$obXEI(M*31|@tF0C3Y0toE;8XDbq%D^nBp{=y^ z==DeUk}f#mZOmdCYhr_3k)(~Fz~N#xKfVP~+v0O-stLy+moF8Xpg7QNCxKrzFXj32 zX!WQuzW&}Irq<N@x-&m?N*Gjje&K7pg6uSnv@qb5RidKhmH|IMR;8~dtAfpyqZFL$ z?17t?LMeq`&$1SnbDX%GKnZ>KTaBGZc4QDit>u7`PNO?#X;pyecQ!){t_XxsLS<L} z6V&0veW>@!Z&-ZIeE?ntiK24Zz){qc*g3iACOh0i?cHLf@_aP9cy3(v@M2vE|I$3j zd@&o07NOdPaVaUSQ3p?Ke+BdH+33=^i6+*=*z-^Qc+gJ-rY?>v*vfgDPA$afz_jE8 z-<Bxc9!6|scE5p4mdhz1egIgDD=Sh3T>sRMCs20HTCne&)tO9N?^&AI8xWLd_496T zdKlA7o_SoaQ0yNMnvW$u9t~P-KDpu;WiwdYPHJ3GAIQP=K<#+mVHEzC+VT9N(o2~p zvR7K=&>(rUJ#MGBSCxH7LiCiX`gRUwe^6RWBgzINY;Fed+FK@kd2rFZfDOB1ANG|) z-9$Ug21*SD&^s5)0z!vsST2JFrWaWrf9N}@G#T`1GO0ZO%}|pcXfDTZHx}UDgTJG! zMCL4`)~&!AIn9J!TSoP%VDCPtTJIW`8f}+GHZ(N6v5%24%1$<s_8SqMYhIMM9NY)G zZustJS`RFKCur&*GgS4J`ciE|kb3I;NcPC6aFtnrocnO{%F~cst34pXhY4x)>dktB z@4Qy&Evk%rloGOJ4Zcx>+9|<|?~lGJ8{e_3yxX~D-@4BAytUQ6zWz_Q3vuWoKuwj8 zCeX&RIaQy144;({kByPPx*Rn+X&GA{^8IsVglS#e9DWr|;X4WXh4&`JM`zsySN>>v zRKOtn)ybbl+5fTo<1fU|e*vlf6*>N=>G$pjaq^u4x@P#Bc*vEU=LD^Fw(Uio^gk^Z zx=))->kp|^Q%uqCO(>5FU(N3D7;+Co5Ed=8F?GEJ{<NOOU5!Mm@9KKzCQa6Lj`W#9 zI~&x?;7uvdo;E-H<(<t72?0)VjaCn{1FgBWJci_i@|y5fQ4;M9DML21vOQY~PUL&A zyp^OV*cRHgL;ejU?_s|8FARU*b7Js8w2LYt@#83O8(g<rY;GP$p}{%0qLfWZsNL0+ zffsW3$NUd&?!!QW3INlHIXa&$eDc)7qpfxg(*Cwe=U8O2Zz2NNc8HVoF1(ftSf_27 zIhYQe`_?tM`u?Po<6^e;B1(Jw{_j%ylDCmbx~vw*{VUD3YGM}Nhw&>8jZpZiZz4G9 zR%q=h2VkhZAYRKDC3HClc|4#g%-C&Q%IHt|xK=8MWe{>WGT1&U+~HN#witNRT8o^P zm<W9n2oGuvpX=e%=y9o}(6}%Myv{?*7xukv-6vvQ0sclmgFw$z<+NCO7VKgp^d)_? z!^sp~+&A93WSdXN<MCGOEAlCZC>Gc>fr$?a=G|mLkY00fpX1GQMk%8G*-Dh;*r!)o zl3Vfc2AaA>1IY>d%C*tu?MWUA%wqD$auysh9wA;hVqtCYBEi!Mf>T!7i#*z#C;Bc+ zoJ+J`9A;X%mlLX1QJ{A`LwaVoCD3jW&4f_hv<mBG&~p*=8v*afuw(vdu*8}*NpHHH z2JgWrz&wBL(5No4%<Snn8qT!LngV{v)-aCEm$<i-Ez~ba7MO28|D(wWShC)8s|s?= zhITM%sO`(%3efhYnSB$i16YLMC_ol=gFX%2c1o^WK_#B{(k5}`vJI%0GO@1Eb?|HH zept#N)L9JLcd&IV*KaU~d;e8av0tPZ)0+8z3sx<RGnpQVpC-@s70}sU@CSsl`Iv*r zpE}xKANJfMZ_KTs&~iM$kIf~V4x({3VgcF~P7CN7p}THhJqf}JuR%k<^f+H^c3FDW z&Pi6h<S2*=I;UQVwf)fjwW`MD?dNmkNsE>#>Sv?d)}@z#t{;XpYgsj-zL~)7)p~PX z+&1uia>{MLm0=Sk^5Je<%$UjYeGg$TYumvrf+auF7BgwWYC3g8kAKX>Y|s%%^5ts~ z4tCHZbv4SWH_|g=kCk@7kMJO{w)=gg(=-g@Zl_}H@EDxjUQ{ePY*O7ryVb7kOR5x* zaBe8(Pu0lv_7!g!=YRLE`5httP@-ODx?q=&Q&8vBq~-~M`aXLRq)`i?DUlF|TDB`H z&tP%z@>kDj^Yzv5pt=?$ntg+HI@-*nLoppp1VuKm9;<81!C`cQHi;2xGt<ND&bOTe z8>R6JB&{z!evrHLV0u}Y++DPbKGd7Eq9tinfKgf4O39Z`c`q6l)D~;t60j!bNZUFv zb3^LJX~%}Eo8MQTdx{&Ty)HQ_7i@A7K%!Xxux6)*VX$5u8Bf2STV1YLMgHL2n3kT$ zNa+_aGq;$k4&3(d>|$s~ObD)ad>Z|P9zd8x%{qIWWs?GpSNJc8;*JtM=taq-QFj4+ ze7phvsm9<$NF_&jrusX~^;Pd$GBRr1;oFVuO8(w1j|vMtyLAypU|RmpfDz&aPeYAN zJl|`%(8-p27`Y&~elb`XKco#VDMlx!*J~(VvEobS9bON$8+FIw4Ao9$+=^3rU&PS2 zDmm@Acp;wgMkrrXP@h;HvOP?v<Q;YRO6GbALA<wTJMyZT2@(-j!x1%pXJ{vRSZO2q z6H?aGcG|-aZ`mqD<(JUW`q=z1iBWfqbZceT1LUB^k%A-1`5?MXJi&3O<Idv|u2PWw zImz1Ym24RmeTmFvvO?37Vc#W0nWJul^+`c1qbR`U9<4@}9y{Km$X}QY2Mr49lBAk` zhcDb*y<SqZsF^XUVpg**`1M?fb%}<IF7e*C$7(tsaw?+&imbY<?PJo>K(_lsCNyIj zB#04{+VG7@Q6-iowvlq2wyn+Y@$Ic51Hs?KZw71W$<7Xc-Djm|8FMktaK)Uw=a37p zEgDO${7UWioY!((x$|<m-D{RrzG<l*^tzha42@7<Frp61>@O`1p1NMd`So^gB}%me zr~UrOpeTEX#7d-MC+OL&Iq0u0RiBn=`_Vk=dRuMUGSWGL(I}>a`cP|~M?5y_J+};! zo3}z506^(=b}R$A|EB+bMl`>KtpN7;WR2zx^t7w$@R{iX>lL*GM=6_zlr`G;TJ25( zy2!s7aTR;rN5WAn`J9@B<HAx-a=VXG&o|92psOx;^vfhrfCQveUAam=(Hn73ak_Hd z@>LwnP(D*^%U$=gwrJV)qNWP`eA=$LT6OoST8q`S`kYxjf2q-6d9I)=hyx8%jf+5Q z-9iM*M@+bXNa(&7yKv)8KxR6wHw04x44Aeo-!~b$SNAog%+ifI=0|K9&K(YjcufkG zRy0BK&-SUc9l`YyFO54V*H1J4YI@|cFziXMPbJ$VSri&3L>SEcawaf9Uj1~#xV-(P zB`{<je{Y_2@s#BN$qUn)%6Lz}w!=K`F9&3RN}=CdN92K#X0iOUXC&C}%wCtEPY>wj z;-s|fMk;;Jh4jnLTte<k$K+{7U~R8Ah&usm^ciH47P$PWTArwjtDR>9$)C}@=JzW} zgL$nSB{2&xqM+nYLN?tmLwED`ra$#f+n!Q2WTp_xqBWRzd6e+cRN5!2CL|i)BJ%C_ z6{$HVs|eHP%Wfq@^dy}No?GJwmA7rQz61)YZ0MfSsYNl&q4O$b>N<yPoRg9<ZOaLR zpH$w#ovbQK$JBvs)$#b}bWAa9KAOvWy8EniNAfBhbC*6ujNWgq!<K~GJ-?of-rABi zB%i|987*Uk(k6!s9fkDjD0#zJm#aPZecbxGQaPjDJlJNA(G&e6`7;C312CaGQRC_X zM<wP@7(GG2t}9^`GR92Sf4lCo=dCv6A!Nfs3>L-jIrYIEhS;cl*O}6+5uYO#XfBPz z%`R(x9QzsaMY+GZhuI*SkJfR3U$oDyiW$rs-C`0UKl@%S)I-t&9KSdjHlQL9@Bau{ zg&g-4Ve@OttshIiac_7IUOtn<nvt$B@=PhuB#ryn27azHX%!L2fj7NxgF<Y=@t&67 zdv!iUI9EO_>O$2nbW%v-?fZyt<D)k^UgwKwxC6wl04d8pVau_#IeV9qSi=L>AA~?$ z6}mnwwWiHN2{N-Qpt1Opc<YDM>r}W?+-ZIbG|{Lf2a9;TfCofK^zGX?<L2QZjTYJH z$DHBrs{V45>fb<`L0_CZl-F6LHT2k_m3O5<y~!Y5`@HZP|AeB8`n!+l=5|Je&OV4u zI0kL}K5DWvOrvFOZrWd=IUuLr%;%PmDkd6VyUvNKm+zA-Y`+4T*oHOJy-p3NE0C|1 z**q1R*j8o_S#Xhmo;~o<-zgm?hytqMzanFQeGOib<5boXj<C85+xMCUn_e|T2)QQH zzxIz_!;oU<C<EftigBsDU2o+l(t=B{@8Z-TNNQ{knS*7!L7Q*@qDdy8H&eN*<^Vz? zDrfDkF<-c?Tnsr_`jy-r_kNR_%K5Zh+gBKmuzmDLdaISt0NpNvo<zZ)A`_vxC#m(T zjgW#(Qf?!;wgUeXraT0@uXWurw^esOV4QD^>sb5wBNV;PiitZfE03~~IpB(dBxtQN zyNPiM$?!97hRu^JKKtIcNHuEb`JS>rY1dRa-&0y+TN`F&g2gk^;E#jE+C?7eP<FG_ z=h@Ygz%2ypbBBXgVgs|n2}@ij3%}LB5%0loLD~|XhF8!U*?I4DoiKQI@zj?r<};E} z`9h<RbH0d&A9iXHDyB6(o#=TbY$8JjY2R#9y6@TkBMn0ecnE;NJVD20Iw<F7#^{Bc zh=!+@iEWejLYu5cgG|}Nh6^s2x{&9j=XeeAP2c9e_|U>|E&KeUuR_yO1iT)73Ly27 zNu{z}(`-(Z>&@0?y)$Wo^-N<Ej|+buznjf`Ez#nbh5G4q?L^yCr;G1VAJ&e;-lIbd z6H+}83Dz8kev^=vTnJqh_TZ<TVi|yjRD?MY^JsS`>uV1`In>&=Z%A8gCq00xqRy*} z?<7p(+fRyU&nXY!G;Xw7CMhxTrtwt>SKF5SQ%f+wYAj5-6oOnZP;6@+prGx(VEEtv z08$JhJiJA=FuM_NXaj(dB0y|_$#LK_51QI3<h)NssoZtk`ooUao#f4g9Qp8@)?oy6 zi2|9!oRH(?O`)Xa%MT&d3k`q;1db775KH=(QSgKm#c?0e7$($yE8&@Ev0-AC24>+a zrG3xqV=Z6FA`!-c%6J8hsMKa0MhH*z@^0a3rrsRTg4#oaEp!}o&IGN~puCvxhBM?0 zR0NB;=1k|gxWtz$@QaeqTie@xFv?3n6v2u?)sc%bo2lut);^8>J|g!!D!+<jQfvcp z^5+W;+{K6a!h<_Hfxdtl&)t;b>gclgph|`>kE+WoUPGB%t7cZHnh)3N|3B?rc|4SD z+a9VXsq~aJg?hBwD?%8a>@lbeLPIhpW^7T}sVtQu$-ZTsk{M--tPhXu#y%K{EMu}W zBZPUcdsNT!zJI;n?|Z-RkMH;OSHE%J_ce3f*L9x9d7Q^}o*PLXa9$@T-+2$j9x71{ z5js{W=XNT;FwgWl(P=$JuAFg4<P+Nu6Pg047Usfh?U&obmfX;J7R}_XR!ZI~UW00> zj60n!d2*p(Kv2yJOtYDzV~1zuu3IafTUwy6&gW0Y7G7o{=C7>K<Dgw5hj!!`_8DzB z_zaDx)K`7&E?oyb8S04ac_b{9IBiH73F05=vV4LhA6I@x42%thez=R**{U?`Qb2mn zn*=7!B6og6B~TH_B>)osPE)YMtb5*8ij*;(kI#Nm2e$+yv-0oYfB#YHVyFi6xSL~~ zSUq*FSU|=?eC^bM?5t+X?VOmmW(pSK7Fk)xgMfh|ij{br9Q?fn1DU3|y--R!fR`0? z1(7==8f11|Yv@|;u^FA$q+c)5U#dT<+k>IBBzu^-f*SCS`;K^LNn?G*`$%62ULfLy z8G)#K=(<M37|#5xQUd%!l4>WNN6b-0GE(@Ja%fjDZKHrf`*L^cQQ(4L&{SL&mZxL9 zaZ-%4kdI&LIhMDTzRyPr^w#!rOa%`Et=<8307u=<TRKBqkO{rYby{A)sIz<Z-Ix3F zT^F>q8($y%qQu?Z5_V04z~6(^mv-=qihlJlQ6(aN@=Wa~`=^jAd+~%9_7t$S&D3=c z(CYQrDSYCsR9i&cDqj=Yf%9?ll>RkW_1~|VY(!oKjSsu_luOKP$ezsIp@W6G&4ZIh zt$($aoj@6laUZt~v8a<UQ1$1QbEDL(Fr+6)=#WV}h_Z&coHl_~sm^>YonlhNaQtV4 z8cclPuM?amQ;LwitE$SU5gp9uQ_P9DATIk_%rAf!i|dfwz?wr_VIq(hHkVR20?c3d z%(k5!Edw?0^1Q#w+xF(Wre$FpZNoFt@?TEb$`-uIHt99-O+<2!?j%!z7+EJoUurQX zji8Sp<TOq$?o9^~ENF!ezdn9)%2xjiFVu-Pki^^K^J%WB%*xgy&hU!Qma3v3S`i$Z z#_ZHe&6VBE)dwv76s{iRb@CMz)ZVReZf!e!Mh)_+h9u=J0fRt$Q#W$zE74yVX7KNH zru|M)++}t(BL*Ed78tp*I1d?#NCIzm4$G_%!QohcP%TDg7pQ755mq(%IP#E|o99Xa zAUx@2LyfEo1XFdZ{O_Z$vh&Swj7oDz|2p0#&20T6rQ&WVx>|aX{@w_y9J|4*GxEGi z*=;M==*}Jg+HV$hGKpVx<I-tFrbzemR}T-ibc%fHw}tx^lp6|q))ay10$d~uDvt{V zDz4LX&iVRzB^j(#@|eQ9d>U%R5^`WS#CJ)Lcys)GG%Gpw;!a<n--!#2^4bRPV4PO7 z^lwIjo|UWz0t?MCq|=_P=r(KTFA<|Fino9fK0d{~4cQIU767?ERE%|Rk+mKCo&Iug z&RTX}HD0OG?AQU%w~S!XzQS#Cu0tpOZaNmH@z@QJ>;Wn0@01XDCoFgh9`>JrGteyj z^MhQ<SO7<JTlM|+(!PMyo1^E|qtFfxnJW5L{044P=1cmNF3axKYLaZ%K}Slx(#it^ z2whO;Ao`}9l>y^Hg>2WZk;&Me&d!L)-`ySa>J?I9UPh?QEYl_L<Cir$G#8v;qlfW; zV_UW}mgki>%|>>cSE@c@G^fbjA2CUroa(=~5V2a+IC*&7ZbF)vW;V5G8Nx3rpQvee zXzk3o+@gHw>-Pf9R+ZADtnP5><c6q_lI5F;jT%hhl5Zug#?f(;q{3pNjZeF>plgy9 z-H4;u>~$6?X5iPR!S$1Sjz}ce8l*#cd`OZM@Qxd;gWXsB+9rCWd0I)9e>$#^BNQJQ zc29O|gUKhc?MWY#?0w#PM2KU9V$NBV|GIKX{=qY?<k!fJ;`Dc7xsd6pG63j(c5I!h zjaSLh?W}B;ty31v^gwTynpCYTGG|1DXBU3*gnqvSICKHliqDr-W!mEY?pL(x8L2+d z`?Efy5Z-jAMqt=agEp@0hTw4^OdFzy$FDA%-g2&4gy#B&^){Hx8~4}rIl|Q7`tFAe zT%vpYnoV3mNT1{~rO3<qz}W|@kwtKFgHEv(qNFPO^tE2u!^uu#s&_J6X8Izp^5Taj zIHemw&rgVS2_X24P8s($h8VPES<v_vsW&F`i=7killK1L+wm9>;rl!$JC8xIu8Ins z7cu*ztsY;D$_4mq0tI~<k>j6=jSgT->@IlH4a$6ia>X5YJ~G+PeTU~P2GYe29JL35 z{pKxf;5j%^FNc}W^YM28{V+Kd(MC5}9<iJ&Xtv2knTUI%-t>&jzX6;j3?`Jv3N$|i z_g5Im6;^|*Pw@&@#EM^WI%;9(U_-pF-F*)^uJ!nX&|ROxpV@9`)T*#F&&grjdV#GO z+O^eN(K(rqs0^=7)Z))O-eL5*f>01kW8&(=)W9h88ej+`FWFki<xk;lhDX2N6jLo_ zKV%{Qh?}tI#DlES7;nEF8#6iCNRVnTkxu67niKz3Eu<N?4cetD-)^~YAF|$Hvlfqf zNUPRZF66^zdM@R}b7_olhCcjOB1}~2D|l0xZ!ESJRrb*-8S(;Zdv^J^%ZXOuZgj)H z#SB<(&^*jkl<Jsq<r_`Ta)7hjzwgG4*9#Jdz6&sam}c0J$8hV}n#%a=Jvll${@dfd zo*kRy7tt{yB0u%?=LcK>8h{!ZP=!F~<6ba~$6g?U!X0ZiF{I2|W`FIC6X)B#$M|+u zo=HEo7PHS*l&t*R<8_fW0dUd~K_Ct88S4J|Qf1v`XI3IBCIR?8{6lpFsj8^9KsO1} zLYSS0K>l5S4qDq#6bJtOb2`4aiD6|JoQ-pGtVM47K$bfmCCM$+phcX8$Oaf10N*$1 zrZeY3v>Gq_>D89Yy_1Y{WDVnE5?5X#J$8ai0+3+2lo_1e0Y^{cMexRcW`~q7eX=w@ z>L@P8xBGC}A%1D7-wW&wBwti|v~Q-5z3=edIZavL3RJ<dLyqE4d_1HoR&1ef2r(SJ z7ZJaGi~6>tAGw}_vvIYCTt6$&^+>Y!@>XbAuO;m$mT>$dB|0TEKXM8xFAtSc@&}sQ z0N&(=$040doeIOB19aUi7+0UoK(7+AMKC4K%arSIm81=;{3HY5(9T=5YcYo-a2BBv z;@%46l%~q#DEKo+9%#6;!UZ~HWh~E+o%TPT*#d!X)jW}mUH0Nx7Z9@C6-(d+vLfW= ztdgFAQa6?6Xx)(vOn=sRb`QT_R_gc-iWU*)+f4-=FKq4t6vnodg7>nkW?+(5r}xxc zDEP2MoZu%h?PQdOY8JYK3l!Bnwo|!K_;#reDkyTg=Po{FecXM+72FSVt_4t0=VC?a zQ)Pr6Ty@xYmqO453&YNNT13406-U~JCIh>(QTq$!kpq%={RBCi#<KSq!;Dmht^)h> zWM>}CIkO3t4LX(s68P=oaq})!FAgdm+@+(}v+E+Rcd;>Q>sUn#;Ub5XY`B&sCi=4F zBazQGgm}2s%@MWT>-J76g}o_yGIRMWF(6L>J7fbkhLXJveZ|-wZL|7}0>9z7<`s&p zhRbh<Y(68A7!s>x#3y|dO>n=Hv|1k%<u*Mj8p6GTb=U-pxxj>aNT(=Bt`b%gldLxy zX9}OZDCo`(FH^j{43=8JSL%LX9MdE(=k4!az3+$!Nhpy0Q_+fVIc}O(v;Lr?#brGH zM3*@wrLo$rbcGTR?Is0o5b@v7v>=8!qhHI84&;+yI`{@{bQ-2Acw2S3RT>=A)b-$( zBPQLPrR5%|D>Z91PbWt*(A973(^Nk;`p@VL59A-W5W$x);y0QLS#k&1i@v^N#A-2W zLTO8h=3?ia^`(kDNe`9H&AbILQk&t_DO6<?1Z-g`O{@U@U-vQervPr?0s`J$Ui3&K z2w#&`nY#0sFE|OMjm|5qj*SBR6W9t-K(gqE?pzNAAEv$k{vnVT2HZyjX3#$xGZ2Dy zu$#e9X{7bosOY|2R{UxRq;oDAvaTYC=uO-fwSUC2sJ>qN{_f3WHAG{Fz|;X1@gPgD zM)*U)vW?x^DtSBtKO87mp8SOS>~k%ab{J>_K>G77D8%67?+>(A=bp_Bb3Ytkkk^*N zu^H!Qyg>YfZ6Jzd0-Z)4v+Po_n?d|Qc$jTI(+%BGUsE~G-a{`M$VC2y-y{=**Psle zw{ex#uc$-)Dyqr?h_&!>P~xOP3xz8m*17HYJK~_iBlL;Cf<Oq#ji|y{d;*)oQAok_ z9n{g{Bm*XrRQy@fdinI4CK-2ut4*?!oz1;|ml2E8V!=)>K*s|5dZ2W}69(l9!S!@d zrsgVCrUo9z#u89$GGHVi6$MoRWp)AkuYD(wbXGpKSh>B}PVlCgolla=zW6~-|HPfi z(O0Irn;g(2mT49I1yCtKFeVU8nZE6=t&ospw_ih)tw!eYZiMuQ9bD<vLmK9G%4YRN zm3ckxTAeHiW7P0>jLyij!k;Qs5!$o(@mf6GYp<3-6Mk=+Y9~DB>Tt1u<n&^;Im0oN z-{n0I1HT0w4TDyk2xRx@%^=+B+xuX5%UDIa{p|4UZ#9+4_V4{DiO9-bhzN>bkhulc zRR}WAuq&IH%d^I@HK^EBRe9}-gV(xqn6<Mj{c>9w>z)+^<Z*U}Ptsrhe+j~+bScnn zX4dI|>O!N{{k29Y44H#O`U<Gx$`%s~ST`;<(ry%=tl=DWhdcWf%YQ<{9cto)1+-)s z=3Lcx2^ph4(yZAMmGmknYN@2m##(B@h5*SYpcVO1U?P6E?$1&GOH^bPipcajZH#uq ziW9|Tfa3lYE^b2S>`mV~=qsFnAO)-yClG8}6m_iS&X+2lC9m>UxxG<4^!OZj2chw; zdBNo5Mk4MRUin6=I~gUy#}VEo&yUolJbI+5&LLf2+q4W#-xNr~0WcKkU8Htf=aA1{ zL`p6{VTTUof~ZJxs5ATuG~RCj#@;rLtoIwMQ0cT~9#1ek*b9BmIx+*gwG0Xy-1MJ! zW0%sin8S}zKTjR`Cc}C)JuKa^br9zC$Z)~BtU<AYb;p2-Z%oEF$l>0$fpA!L*HWyZ zA)ZOb;ki}#irY*I+WkF_PypM|DBQ}RF3diR3Aa4}y`C3Owo7)%kpx+=>VGTv0kr?E za#RgDeIcSYAhkrn{$>1WAh9vdRYWa1b-9;pk#is}W>?6`|1I=!5!}@J2$ewMzvlAR ziUUH1Pn@Gf@rdTAhNY4=X31@Aj#wG?DXDvf28wyc0f+!A(|InEYxptDa|scjd_I$a z>HON_OQc;o=dGd?;on_?!TgDD5=|@O1hgCywda()y1y%LtxXE`T$w=0utYWca7w#p zVG@|BsXB<q;fl7SN|Q4CCr1MBvqh=1+Y^f5_;f+?=P!W^Cwa_CTA?Tjsr(ZK$yco} z&aANfp%`&^d@}~pT)YLMpR)kt1JjFpMsGODWVrVCb7CF4sZH^F9~7Jky}z|RXOVET z?PB8mZ-HBmkjU|28Pa^BR$?YFTSyXoD@i=}7s~se;Xv6=XiXd(U&p9xAE+!dqYP;% zoIWL#v;TPSpNrSUyy=+f5@#f~axrbluhJ@)46O7)fKmfSAhLZ(Gfn@7?-Fyx^`5LG zDl&3+WC^3Nh_OnakHkuU;J1I54!HH6{taV3lqI*3NM+f{w&l-fk*1&^9|uWS<9Fkg z#k4;_QPg!mRY;n*-TUiF(>JfbrrhGF5*}cN%f;La=L$}E+vS70_*S;nCJyJ{@u*KY z3z=4t8PVC3ewo-;=|?1mV&WxBimxCLi6xU~lG^DQ^DLJm-rMrfe4^SIb8bbI(CP>z zA-}}kc8p4;-Y!MVzF&X|-DKi173=OTz=Hw?kgCobd;<QSK>Ga4!uWW!$!3M2rn>E{ zj2Fu^!C*+#iijywcia}_PVu+E?_ZYzUI6s(qc`+WU>|`3L@i|0e*#)JYT;|3?Z$IX z^)gmL$g(`(p+o*AFd51LNx^{UP$0rO1Q0Njq1ZTAZ~4m^Nw?j&K@&m6bI+zpHntvb zQ&Li{2>_)X;Fw`mY%ESe1Q*|0w9-{{;-)}lTlD_hW#NBC0$~tQ3M$Hrb5A4`933Hf z3w~WwWKAxl5d`V!aL~>ELm_)YNRZdk8feGIQXV;{N;<>4&7)dk(y2K)po-7tF_m{R z$E3&x&CYsviVBe;12C{u%C@jhXdLJ};_X+C!roK<)I;|fVjZ5r0UHbuky`ApxrxCd zS^fO41GfqGzdw?&Gn2r-8X3mf8w<7pYWCKi{rBbRjnpZ&Irso`g`;H$J=l4f*x=<q z;vrJ;WRqTp)_9eY!-lhidhJ!F9^mZ2n&%-wKMq1Q|6Scaw0eI&s7miD#K*q$u{~vd zL&`u9H1oD3(1$*sd~WDC|EKgB>R{IRx!f-nZt5-VML@dkwek(jMBOT6?_m@5EalnE zt)-6>9u7XQ4=Os^5cNym1=a61O(*mS{|+ZZ(3+hEtv3Z%VB2VT`ewT~mpOMp6l}R< z_@~5ml9YSB!Kl@(nZEt=w1o#R3FiT$9c8N1+|p)cY5Eo@{JEsHT9b9uCnH_-U#`W0 z?ow+YajbR}3gQ&Z+_-!V6s(QH4s!jHaa4T7xCqGsuRWP-cLS?(K+@}NadTRm*X_HS zB~<9>htI3xU^xh5BNyWg=H;3FQ0-!9LbN$MUyw+2!|TzVIb+YA1dmf{R&9N+P|^b9 z`F8sHUE(=zY5mrtPaK<BI@zUNk&}qE5>ZU7x4NuH1Zo#`C_)7J$$LurSt9M}=-jDm zHOli-TNh33QYguxbEBO+e4@^+Jbr*Wz6anqZ0@&q`bxZ{4WAy-@!Y_(vA6(fy$z>A zv9!T6EkWP*W+n_b%Uyg~Sfm;iM7_P}Pq}s+kSeUxc)5{IZ-mPMjtrB}=+95>(4D^+ zH}NpHJs2cO&L`$f=u7`0d|EDH?fG`SwE9qt`Hf5?pfxZ*wkzS-YA0ch8phMA;+@BE zjkn09kt{<Qr$A<OzX_p3Zs$AJnb43&<M`QCIX|?;-04lGkHxLPsxThwCL3UFYC~c# zmev@@{-4nr=l{Rf`2V)n7~&l#su^BSk}=-8$u6Z|KDKnrl3n;5w^fU}b$6a7SB*Pn zMx=}OZAfSVKhF(Cb!z;12P*vroZig(^L38glQ%5Zj;L$#;io(UjVoVZSdTP5m!zyB zP=O4)92){R&GN~ZmJp+4$7QSX`t`wTjyW~}Oj$Kbh7OwrT+cXDhu`WR`%ns#iM?Rg zq#^yGRW_qCJs$#><aZ0MeN5xUplx7uAOrv!B;C$G<w{24Pg3pUk}h?0dQ`=(`h#l5 z#;dP-vU?C9PZ*#AZTf&Ka*K88ckp7@YE4_!4EaxKq~X3<zO7XVGRGGF@EyJo9SJ+( z>ASidH(tGC*=^4mfej>AaRbd1P8nJ$%1Vu4Ig%8R)&a5>8I_HUmZ$xoKO;X0%* zAF{ZfPGia)7zr%>Dx0F2swx-3uM{`!f{1#frfv~q>y}!;IPc$ak<AdenHSrILo~_C zd%2*%rR{~{-N89|C$eq1k{Zcp^)D9#Yl>%528>+E%(QPz00q`reGkCs|F+NoTnm_a Yx<Ag#DX#bEHC8~bt7)J?Ja2vPAM?yk*#H0l diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_12.png b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_12.png deleted file mode 100644 index 784db0f2430f2d939b9a80e1e00ed6ad5c6bec9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51622 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 diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_2.png b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_2.png deleted file mode 100644 index 1a171fc0aff0c42169c6f281ae526a3c48183aef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55531 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�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%0AU8 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 diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_3.png b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_3.png deleted file mode 100644 index 2a890bbcfaa9a79afd5654404520a81109573683..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51880 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 D9YUn< diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_4.png b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_mscgen_page_4.png deleted file mode 100644 index d3839cf09737fcac333212f217f84f3492699ae5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54607 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 diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_usr.cpp b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_usr.cpp deleted file mode 100755 index f1c09fd984..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/mih_usr.cpp +++ /dev/null @@ -1,1457 +0,0 @@ -//============================================================================== -// Brief : MIH-User -// Authors : Bruno Santos <bsantos@av.it.pt> -//------------------------------------------------------------------------------ -// ODTONE - Open Dot Twenty One -// -// Copyright (C) 2009-2012 Universidade Aveiro -// Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -// -// This software is distributed under a license. The full license -// agreement can be found in the file LICENSE in this distribution. -// This software may not be copied, modified, sold or distributed -// other than expressed in the named license agreement. -// -// This software is distributed without any warranty. -//============================================================================== - -#include <odtone/base.hpp> -#include <odtone/debug.hpp> -#include <odtone/logger.hpp> -#include <odtone/mih/request.hpp> -#include <odtone/mih/response.hpp> -#include <odtone/mih/indication.hpp> -#include <odtone/mih/confirm.hpp> -#include <odtone/mih/tlv_types.hpp> -#include <odtone/sap/user.hpp> - -#include <boost/utility.hpp> -#include <boost/bind.hpp> -#include <boost/tokenizer.hpp> -#include <boost/foreach.hpp> - -#include <iostream> - -#define THRESHOLD_HIGH_VAL 90 -#define THRESHOLD_LOW_VAL 15 - -/////////////////////////////////////////////////////////////////////////////// -// The scenario coded in this MIH-USER is the following (with mRALlteDummy and NASUEDummy executables) -// +--------+ +-----+ -// |MIH_USER| |MIH-F| -// +---+----+ +--+--+ -// |---------- User_Register.indication ---------------->| (supported_commands) Handler next msg=user_reg_handler -// | | -// |---------- Capability_Discover.request ------------->| Handler next msg=receive_MIH_Capability_Discover_confirm -// |<--------- Capability_Discover.confirm --------------| (success) -// | | -// |---------- Event_Subscribe.request ----------------->| Handler next msg=receive_MIH_Event_Subscribe_response -// |<--------- Event_Subscribe.response -----------------| (success) -// | | -// |---------- Configure_Thresholds.request ------------>| (High signal strength value) Handler next msg=event_handler -// |<--------- Configure_Thresholds.confirm -------------| link_get_parameters_request = 1 -// | | -// |---------- Link_Get_Parameters.request ------------->| Handler next msg=event_handler (link_get_parameters_request) -// |<--------- Link_Get_Parameters.confirm --------------| (success) -// | . | -// | . | -// | . | -// |<--------- Link_Detected.indication -----------------| link_action_request = 0 -// |---------- Link_Actions.request -------------------->| (power-up+scan) Handler next msg=event_handler -// |<--------- Link_Actions.confirm ---------------------| (success) -// |---------- Link_Actions.request -------------------->| (power-up) Handler next msg=event_handler -// |<--------- Link_Actions.confirm ---------------------| (success) -// | . | -// | . | -// |<--------- Link_Parameters_Report.indication --------| (Threshold crossed) Now (signal strength will decrease) -// | | -// |---------- Configure_Thresholds.request ------------>| (Low signal strength value) Handler next msg=event_handler -// |<--------- Configure_Thresholds.confirm -------------| (success) -// | . | -// | . | -// |<--------- Link_Parameters_Report.indication --------| (Threshold crossed) -// |---------- Link_Actions.request -------------------->| (power-down) Handler next msg=event_handler -// | . | -// |<--------- Link_Actions.confirm ---------------------| (success) -// | | -// | | -/////////////////////////////////////////////////////////////////////////////// - -static const char* const kConf_MIH_Commands = "user.commands"; -/////////////////////////////////////////////////////////////////////////////// - -namespace po = boost::program_options; - -using odtone::uint; -using odtone::ushort; -using odtone::sint8; - -odtone::logger log_("[mih_usr]", std::cout); - -/////////////////////////////////////////////////////////////////////////////// -void __trim(odtone::mih::octet_string &str, const char chr) -{ - str.erase(std::remove(str.begin(), str.end(), chr), str.end()); -} - -//----------------------------------------------------------------------------- -template <class T> std::string StringOf(T object) { -//----------------------------------------------------------------------------- - std::ostringstream os; - os << object; - return(os.str()); -} -//----------------------------------------------------------------------------- -std::string getTimeStamp4Log() -//----------------------------------------------------------------------------- -{ - std::stringstream ss (std::stringstream::in | std::stringstream::out); - struct timespec time_spec; - unsigned int time_now_micros; - unsigned int time_now_s; - clock_gettime (CLOCK_REALTIME, &time_spec); - time_now_s = (unsigned int) time_spec.tv_sec % 3600; - time_now_micros = (unsigned int) time_spec.tv_nsec/1000; - //time_now_s = 110; - //time_now_micros = 22; - ss << time_now_s << ':' << time_now_micros; - return ss.str(); -} -//----------------------------------------------------------------------------- -std::string status2string(odtone::mih::status statusP){ -//----------------------------------------------------------------------------- - switch (statusP.get()) { - case odtone::mih::status_success: return "SUCCESS";break; - case odtone::mih::status_failure: return "UNSPECIFIED_FAILURE";break; - case odtone::mih::status_rejected: return "REJECTED";break; - case odtone::mih::status_authorization_failure: return "AUTHORIZATION_FAILURE";break; - case odtone::mih::status_network_error: return "NETWORK_ERROR";break; - default: return "UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string link_down_reason2string(odtone::mih::link_dn_reason reasonP){ -//----------------------------------------------------------------------------- - switch (reasonP.get()) { - case odtone::mih::link_dn_reason_explicit_disconnect: return "DN_REASON_EXPLICIT_DISCONNECT";break; - case odtone::mih::link_dn_reason_packet_timeout: return "DN_REASON_PACKET_TIMEOUT";break; - case odtone::mih::link_dn_reason_no_resource: return "DN_REASON_NO_RESOURCE";break; - case odtone::mih::link_dn_reason_no_broadcast: return "DN_REASON_NO_BROADCAST";break; - case odtone::mih::link_dn_reason_authentication_failure: return "DN_REASON_AUTHENTICATION_FAILURE";break; - case odtone::mih::link_dn_reason_billing_failure: return "DN_REASON_BILLING_FAILURE";break; - default: return "DN_REASON_UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string link_going_down_reason2string(odtone::mih::link_gd_reason reasonP){ -//----------------------------------------------------------------------------- - switch (reasonP.get()) { - case odtone::mih::link_gd_reason_explicit_disconnect: return "GD_REASON_EXPLICIT_DISCONNECT";break; - case odtone::mih::link_gd_reason_link_parameter_degrading: return "GD_REASON_PARAMETER_DEGRADING";break; - case odtone::mih::link_gd_reason_low_power: return "GD_REASON_LOW_POWER";break; - case odtone::mih::link_gd_reason_no_resource: return "GD_REASON_NO_RESOURCE";break; - default: return "GD_REASON_UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string evt2string(odtone::mih::mih_evt_list evtP){ -//----------------------------------------------------------------------------- - std::string s; - if(evtP.get(odtone::mih::mih_evt_link_detected)) s = std::string("DETECTED, "); - if(evtP.get(odtone::mih::mih_evt_link_up)) s += "UP, "; - if(evtP.get(odtone::mih::mih_evt_link_down)) s += "DOWN, "; - if(evtP.get(odtone::mih::mih_evt_link_parameters_report)) s += "PARAMETERS_REPORT, "; - if(evtP.get(odtone::mih::mih_evt_link_going_down)) s += "GOING_DOWN, "; - if(evtP.get(odtone::mih::mih_evt_link_handover_imminent)) s += "HANDOVER_IMMINENT, "; - if(evtP.get(odtone::mih::mih_evt_link_handover_complete)) s += "HANDOVER_COMPLETE, "; - if(evtP.get(odtone::mih::mih_evt_link_pdu_transmit_status)) s += "PDU_TRANSMIT_STATUS, "; - return s; -} -//----------------------------------------------------------------------------- -std::string link_id2string(odtone::mih::link_id linkP){ -//----------------------------------------------------------------------------- - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - std::string s; - - switch (linkP.type.get()) { - case odtone::mih::link_type_gsm: - s="GSM"; - break; - case odtone::mih::link_type_gprs: - s="GPRS"; - break; - case odtone::mih::link_type_edge: - s="EDGE"; - break; - case odtone::mih::link_type_ethernet: - s="Ethernet"; - break; - case odtone::mih::link_type_wireless_other: - s="Other"; - break; - case odtone::mih::link_type_802_11: - s="IEEE 802.11"; - break; - case odtone::mih::link_type_lte: - s="LTE"; - // address copied from UMTS - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(linkP.addr); - s = s + std::string(local_l2_3gpp_addr.value); - break; - case odtone::mih::link_type_cdma2000: - s="CDMA-2000"; - break; - case odtone::mih::link_type_umts: - s="UMTS:"; - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(linkP.addr); - /*index = 0; - for(iter=0; iter < local_l2_3gpp_addr.value.length(); iter++) { - index += sprintf(&buf[index],"-%hhx-", local_l2_3gpp_addr.value[iter]); - }*/ - s = s + std::string(local_l2_3gpp_addr.value); - break; - case odtone::mih::link_type_cdma2000_hrpd: - s="CDMA-2000-HRPD"; - break; - case odtone::mih::link_type_802_16: - s="IEEE 802.16"; - break; - case odtone::mih::link_type_802_20: - s="IEEE 802.20"; - break; - case odtone::mih::link_type_802_22: - s="IEEE 802.22"; - break; - } - return s; -} -//----------------------------------------------------------------------------- -std::string link_tupple_id2string(odtone::mih::link_tuple_id link_tuppleP){ -//----------------------------------------------------------------------------- - std::string s; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - switch (link_tuppleP.type.get()) { - case odtone::mih::link_type_gsm: - s="GSM"; - break; - case odtone::mih::link_type_gprs: - s="GPRS"; - break; - case odtone::mih::link_type_edge: - s="EDGE"; - break; - case odtone::mih::link_type_ethernet: - s="Ethernet"; - break; - case odtone::mih::link_type_wireless_other: - s="Other"; - break; - case odtone::mih::link_type_802_11: - s="IEEE 802.11"; - break; - case odtone::mih::link_type_lte: - s="LTE"; - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link_tuppleP.addr); - s = s + std::string(local_l2_3gpp_addr.value); - break; - case odtone::mih::link_type_cdma2000: - s="CDMA-2000"; - break; - case odtone::mih::link_type_umts: - s="UMTS:"; - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link_tuppleP.addr); - /*index = 0; - for(iter=0; iter < local_l2_3gpp_addr.value.length(); iter++) { - index += sprintf(&buf[index],"-%hhx-", local_l2_3gpp_addr.value[iter]); - }*/ - break; - case odtone::mih::link_type_cdma2000_hrpd: - s="CDMA-2000-HRPD"; - break; - case odtone::mih::link_type_802_16: - s="IEEE 802.16"; - break; - case odtone::mih::link_type_802_20: - s="IEEE 802.20"; - break; - case odtone::mih::link_type_802_22: - s="IEEE 802.22"; - break; - } - return s; -} -//----------------------------------------------------------------------------- -std::string link_actions_req2string(odtone::mih::link_action_req link_act_reqP) { -//----------------------------------------------------------------------------- - std::string s; - - s = link_id2string(link_act_reqP.id); - - if(link_act_reqP.action.type == odtone::mih::link_ac_type_none) s += ", AC_TYPE_NONE"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_disconnect) s += ", AC_TYPE_DISCONNECT"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_low_power) s += ", AC_TYPE_LOW_POWER"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_down) s += ", AC_TYPE_POWER_DOWN"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_up) s += ", AC_TYPE_POWER_UP"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_flow_attr) s += ", AC_TYPE_FLOW_ATTR"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_activate_resources) s += ", AC_TYPE_ACTIVATE_RESOURCES"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_deactivate_resources) s += ", AC_TYPE_DEACTIVATE_RESOURCES"; - - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_data_fwd_req)) s += ", AC_ATTR_DATA_FWD_REQ"; - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_scan)) s += ", AC_ATTR_SCAN"; - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_res_retain)) s += ", AC_ATTR_RES_RETAIN"; - - s += ", " + StringOf(link_act_reqP.ex_time) + " ms"; - return s; -} -//----------------------------------------------------------------------------- -std::string net_type_addr_list2string(boost::optional<odtone::mih::net_type_addr_list> ntalP) { -//----------------------------------------------------------------------------- - std::string s; - odtone::mih::link_id link_id; - for (odtone::mih::net_type_addr_list::iterator i = ntalP->begin(); i != ntalP->end(); ++i) - { - link_id.addr = boost::get<odtone::mih::l2_3gpp_addr>(i->addr); - link_id.type = boost::get<odtone::mih::link_type>(i->nettype.link); - s += link_id2string(link_id); - } - return s; -} - - -/** - * Parse supported commands. - * - * @param cfg Configuration options. - * @return A bitmap mapping the supported commands. - */ -boost::optional<odtone::mih::mih_cmd_list> parse_supported_commands(const odtone::mih::config &cfg) -{ - using namespace boost; - - odtone::mih::mih_cmd_list commands; - bool has_cmd = false; - - std::map<std::string, odtone::mih::mih_cmd_list_enum> enum_map; - enum_map["mih_link_get_parameters"] = odtone::mih::mih_cmd_link_get_parameters; - enum_map["mih_link_configure_thresholds"] = odtone::mih::mih_cmd_link_configure_thresholds; - enum_map["mih_link_actions"] = odtone::mih::mih_cmd_link_actions; - enum_map["mih_net_ho_candidate_query"] = odtone::mih::mih_cmd_net_ho_candidate_query; - enum_map["mih_net_ho_commit"] = odtone::mih::mih_cmd_net_ho_commit; - enum_map["mih_n2n_ho_query_resources"] = odtone::mih::mih_cmd_n2n_ho_query_resources; - enum_map["mih_n2n_ho_commit"] = odtone::mih::mih_cmd_n2n_ho_commit; - enum_map["mih_n2n_ho_complete"] = odtone::mih::mih_cmd_n2n_ho_complete; - enum_map["mih_mn_ho_candidate_query"] = odtone::mih::mih_cmd_mn_ho_candidate_query; - enum_map["mih_mn_ho_commit"] = odtone::mih::mih_cmd_mn_ho_commit; - enum_map["mih_mn_ho_complete"] = odtone::mih::mih_cmd_mn_ho_complete; - - std::string tmp = cfg.get<std::string>(kConf_MIH_Commands); - __trim(tmp, ' '); - - char_separator<char> sep1(","); - tokenizer< char_separator<char> > list_tokens(tmp, sep1); - - BOOST_FOREACH(std::string str, list_tokens) { - if(enum_map.find(str) != enum_map.end()) { - commands.set((odtone::mih::mih_cmd_list_enum) enum_map[str]); - has_cmd = true; - } - } - - boost::optional<odtone::mih::mih_cmd_list> supp_cmd; - if(has_cmd) - supp_cmd = commands; - - return supp_cmd; -} - -/////////////////////////////////////////////////////////////////////////////// -/** - * This class provides an implementation of an IEEE 802.21 MIH-User. - */ -class mih_user : boost::noncopyable { -public: - /** - * Construct the MIH-User. - * - * @param cfg Configuration options. - * @param io The io_service object that the MIH-User will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io); - - /** - * Destruct the MIH-User. - */ - ~mih_user(); - -protected: - /** - * User registration handler. - * - * @param cfg Configuration options. - * @param ec Error Code. - */ - void user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec); - - /** - * Default MIH event handler. - * - * @param msg Received message. - * @param ec Error code. - */ - void event_handler(odtone::mih::message& msg, const boost::system::error_code& ec); - - /** - * Capability Discover handler. - * - * @param msg Received message. - * @param ec Error Code. - */ - void receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - - /** - * Event subscribe handler. - * - * @param msg Received message. - * @param ec Error Code. - */ - void receive_MIH_Event_Subscribe_response(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_Link_Configure_Thresholds_request(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Configure_Thresholds_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_Link_Get_Parameters_request(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Get_Parameters_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Detected_indication(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_Link_Actions_request(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Actions_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Up_indication(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Down_indication(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_Event_Unsubscribe_request(odtone::mih::message& msg, const boost::system::error_code& ec); - - void receive_MIH_Link_Parameters_Report(odtone::mih::message& msg, const boost::system::error_code& ec); - - void print_l2_3gpp_addr(odtone::mih::link_type& link_type, odtone::mih::l2_3gpp_addr& l2_3gpp_addr); - - -private: - odtone::sap::user _mihf; /**< User SAP helper. */ - odtone::mih::id _mihfid; /**< MIHF destination ID. */ - odtone::mih::id _mihuserid; /**< MIH_USER ID. */ - odtone::uint link_get_parameters_request, link_action_request, link_threshold_request; - odtone::mih::net_type_addr rcv_net_type_addr; - odtone::mih::link_id rcv_link_id; -}; - -/** - * Construct the MIH-User. - * - * @param cfg Configuration options. - * @param io The io_service object that the MIH-User will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ -//----------------------------------------------------------------------------- -mih_user::mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io) - : _mihf(cfg, io, boost::bind(&mih_user::event_handler, this, _1, _2)) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - boost::optional<odtone::mih::mih_cmd_list> supp_cmd = parse_supported_commands(cfg); - - link_get_parameters_request = 0; - link_action_request = 0; - link_threshold_request = 0; - - m << odtone::mih::indication(odtone::mih::indication::user_register) - & odtone::mih::tlv_command_list(supp_cmd); - - log_(0, "User Register Indication - SENT "); - log_(0, " - User Name: ", m.source().to_string()); - log_(0, " "); - - odtone::mih::octet_string user_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_id); - _mihuserid.assign(user_id.c_str()); - - odtone::mih::octet_string dest_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_dest); - _mihfid.assign("mihf1"); - - log_(0, "[MSC_NEW][",getTimeStamp4Log(),"][MIH-USER=",_mihuserid.to_string(),"]\n"); - m.source(_mihuserid); - m.destination(_mihfid); - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_User_Register.indication --->]["+m.destination().to_string()+"]\n"); - _mihf.async_send(m, boost::bind(&mih_user::user_reg_handler, this, boost::cref(cfg), _2)); -} - - -/** - * Destruct the MIH-User. - */ -//----------------------------------------------------------------------------- -mih_user::~mih_user() -//----------------------------------------------------------------------------- -{ -} - -/** - * Print 3GPP Address. - * - * @param link_type Link Type. - * @param l2_3gpp_addr 3GPP Address. - */ -//----------------------------------------------------------------------------- -void mih_user::print_l2_3gpp_addr(odtone::mih::link_type& link_type, odtone::mih::l2_3gpp_addr& l2_3gpp_addr) -//----------------------------------------------------------------------------- -{ - odtone::uint iter; - if(link_type == odtone::mih::link_type_umts){ - log_(0, "\t Link Type: UMTS"); - } - if(link_type == odtone::mih::link_type_lte){ - log_(0, "\t Link Type: LTE"); - } - if((link_type == odtone::mih::link_type_umts)||(link_type == odtone::mih::link_type_lte)){ - //log_(0, "\t 3GPP Address: "); - std::printf("[mih_usr]: \t 3GPP Address: "); - for(iter=0; iter<l2_3gpp_addr.value.length(); iter++) - { - std::printf("-%hhx-", l2_3gpp_addr.value[iter]); - } - std::printf("\n"); - } -} - -/** - * User registration handler. - * - * @param cfg Configuration options. - * @param ec Error Code. - */ -//----------------------------------------------------------------------------- -void mih_user::user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH-User register result: ", ec.message()); - log_(0, ""); - - odtone::mih::message msg; - - odtone::mih::octet_string destination = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_dest); - _mihfid.assign(destination.c_str()); - - // - // Let's fire a capability discover request to get things moving - // - msg << odtone::mih::request(odtone::mih::request::capability_discover, _mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihuserid.to_string() +"][--- MIH_Capability_Discover.request --->]["+msg.destination().to_string()+"]\n"); - _mihf.async_send(msg, boost::bind(&mih_user::receive_MIH_Capability_Discover_confirm, this, _1, _2)); - - log_(0, "MIH_Capability_Discover.request - SENT (towards its local MIHF)"); - log_(0, ""); -} - -/** - * Default MIH event handler. - * - * @param msg Received message. - * @param ec Error code. - */ -//----------------------------------------------------------------------------- -void mih_user::event_handler(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - switch (msg.mid()) { - case odtone::mih::indication::link_up: - mih_user::receive_MIH_Link_Up_indication(msg, ec); - break; - - case odtone::mih::indication::link_down: - mih_user::receive_MIH_Link_Down_indication(msg, ec); - //sleep(2); - mih_user::send_MIH_Link_Get_Parameters_request(msg, ec); - break; - - case odtone::mih::indication::link_detected: - mih_user::receive_MIH_Link_Detected_indication(msg, ec); - // monitor signal strength - do not change (up/down) signal strength report now - //system ("sendip -d 0x00 -p ipv4 -is 127.0.0.1 -p udp -ud 22222 -us 65535 127.0.0.1"); - - //sleep(2); - link_action_request = 0; - mih_user::send_MIH_Link_Actions_request(msg, ec); - break; - - case odtone::mih::indication::link_going_down: - mih_user::receive_MIH_Link_Going_Down_indication(msg,ec); - //sleep(10); - link_get_parameters_request = 2; - mih_user::send_MIH_Link_Get_Parameters_request(msg, ec); - break; - - case odtone::mih::indication::link_handover_imminent: - log_(0, "MIH-User has received a local event \"link_handover_imminent\""); - break; - case odtone::mih::indication::link_handover_complete: - log_(0, "MIH-User has received a local event \"link_handover_complete\""); - break; - - case odtone::mih::confirm::link_configure_thresholds: - mih_user::receive_MIH_Link_Configure_Thresholds_confirm(msg, ec); - //sleep(2); - if (link_get_parameters_request == 0) { - link_get_parameters_request = 1; - mih_user::send_MIH_Link_Get_Parameters_request(msg, ec); - } - break; - - case odtone::mih::confirm::link_get_parameters: - switch(link_get_parameters_request){ - case 1: mih_user::receive_MIH_Link_Get_Parameters_confirm(msg, ec); - // monitor signal strength - increase signal strength report now - //system ("sendip -d 0x01 -p ipv4 -is 127.0.0.1 -p udp -ud 22222 -us 65535 127.0.0.1"); - break; - case 2: mih_user::receive_MIH_Link_Get_Parameters_confirm(msg, ec); - link_action_request = 1; - link_get_parameters_request = 3; - mih_user::send_MIH_Link_Actions_request(msg, ec); - break; - case 3: mih_user::receive_MIH_Link_Get_Parameters_confirm(msg, ec); - mih_user::send_MIH_Event_Unsubscribe_request(msg, ec); - break; - } - break; - - mih_user::receive_MIH_Link_Get_Parameters_confirm(msg, ec); - //sleep(1); - break; - - case odtone::mih::confirm::link_actions: - mih_user::receive_MIH_Link_Actions_confirm(msg, ec); - if (link_action_request == 0) { - link_action_request = 1; - mih_user::send_MIH_Link_Actions_request(msg, ec); - } else if (link_action_request == 1) { - // monitor signal strength - increase signal strength report now - //system ("sendip -d 0x01 -p ipv4 -is 127.0.0.1 -p udp -ud 22222 -us 65535 127.0.0.1"); - } - - break; - - case odtone::mih::confirm::event_unsubscribe: - mih_user::receive_MIH_Event_Unsubscribe_confirm(msg, ec); - break; - - case odtone::mih::indication::link_parameters_report: - mih_user::receive_MIH_Link_Parameters_Report(msg, ec); - if (link_threshold_request == 1) { - // monitor signal strength - do not modify signal strength report now - //system ("sendip -d 0x0x00 -p ipv4 -is 127.0.0.1 -p udp -ud 22222 -us 65535 127.0.0.1"); - link_action_request = 2; - mih_user::send_MIH_Link_Actions_request(msg, ec); - - } else if (link_action_request == 1) { - // monitor signal strength - decrease signal strength report now - //system ("sendip -d 0xFF -p ipv4 -is 127.0.0.1 -p udp -ud 22222 -us 65535 127.0.0.1"); - // select decreasing down to low threshold - link_threshold_request = 1; - mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec); - } - break; - } -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Parameters_Report(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id link; - odtone::mih::link_param_rpt_list lprl; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_link_param_rpt_list(lprl); - - log_(0, ""); - log_(0, "MIH_Link_Parameters_Report.indication - RECEIVED - Begin"); - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Parameters_Report.indication --->]["+msg.destination().to_string()+"]\n"); - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link.addr); - print_l2_3gpp_addr(link.type, local_l2_3gpp_addr); - log_(0, "MIH_Link_Parameters_Report.indication - End"); -} - - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::status st; - odtone::mih::link_tuple_id link; - boost::optional<odtone::mih::mih_evt_list> evt; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_event_list(evt); - - log_(0, ""); - log_(0, "receive_MIH_Event_Unsubscribe_confirm - Begin"); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Unsubscribe.confirm\\n"+status2string(st.get()).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - log_(0, "\t- STATUS: ", status2string(st.get()).c_str(), " ", st.get()); - log_(0, "\t- MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - log_(0, "receive_MIH_Event_Unsubscribe_confirm - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Event_Unsubscribe_request(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - odtone::mih::link_tuple_id link; - odtone::mih::mih_evt_list events; - odtone::mih::l2_3gpp_addr l2_3gpp_addr; - - link.type = rcv_link_id.type; - //address UMTS - link.addr = rcv_link_id.addr; - - events.set(odtone::mih::mih_evt_link_detected); - events.set(odtone::mih::mih_evt_link_up); - events.set(odtone::mih::mih_evt_link_down); - events.set(odtone::mih::mih_evt_link_parameters_report); - events.set(odtone::mih::mih_evt_link_going_down); - - log_(0, ""); - log_(0, "send_MIH_Event_Unsubscribe_request - Begin"); - m << odtone::mih::request(odtone::mih::request::event_unsubscribe) - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_event_list(events); - - m.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Event_Unsubscribe.request --->]["+m.destination().to_string()+"]\n"); - _mihf.async_send(m, boost::bind(&mih_user::event_handler, this, _1, _2)); - - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(events).c_str()); - log_(0, "send_MIH_Event_Unsubscribe_request - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Down_indication(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id link; - odtone::mih::link_dn_reason ldr; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0, ""); - log_(0, "receive_MIH_Link_Down_indication - Begin"); - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_link_dn_reason(ldr); - - - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link.addr); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Down.indication\\n"+link_down_reason2string(ldr).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - - print_l2_3gpp_addr(link.type, local_l2_3gpp_addr); - - log_(0, " Link down reason: ", link_down_reason2string(ldr).c_str()); - log_(0, "receive_MIH_Link_Down_indication - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id link; - odtone::mih::link_gd_reason lgd; - odtone::mih::link_ac_ex_time ex_time; - - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0, ""); - log_(0, "receive_MIH_Link_Going_Down_indication - Begin"); - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_time_interval(ex_time) - & odtone::mih::tlv_link_gd_reason(lgd); - - - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link.addr); - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link.addr); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Going_Down.indication\\n"+link_going_down_reason2string(lgd).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - - print_l2_3gpp_addr(link.type, local_l2_3gpp_addr); - log_(0, "\tTime Interval :", (ex_time/256)); - - log_(0, "\tLink going down reason: ", link_going_down_reason2string(lgd).c_str()); - - log_(0, "receive_MIH_Link_Going_Down_indication - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Up_indication(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id link; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link); - - log_(0, ""); - log_(0, "receive_MIH_Link_Up_indication - Begin"); - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Up.indication --->]["+msg.destination().to_string()+"]\n"); - - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link.addr); - print_l2_3gpp_addr(link.type, local_l2_3gpp_addr); - log_(0, "receive_MIH_Link_Up_indication - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Actions_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - - log_(0, ""); - log_(0, "receive_MIH_Link_Actions_confirm - Begin"); - - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - odtone::mih::status st; - boost::optional<odtone::mih::link_action_rsp_list> larl; - /*odtone::mih::link_action_rsp_list larl; - odtone::mih::link_action_rsp lar; - - odtone::mih::link_scan_rsp_list lsrl; - odtone::mih::link_scan_rsp lsr; - - odtone::uint i, l, n, p; - odtone::mih::link_id link; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - odtone::mih::l2_3gpp_3g_cell_id local_l2_3gpp_3g_cell_id; - odtone::mih::link_scan_rsp_list local_link_scan_rsp_list; - odtone::sint8 local_sig_strength;*/ - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_action_rsp_list(larl); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Actions.confirm\\n"+status2string(st.get())+" --->]["+msg.destination().to_string()+"]\n"); - log_(0, "\t- STATUS: ", status2string(st.get()), " " , st.get()); - - /*log_(0, " - LINK ACTION RSP LIST - Length:", larl.size()); - - for(i=0; i< larl.size(); i++) - { - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(larl[i].id.addr); - print_l2_3gpp_addr(larl[i].id.type, local_l2_3gpp_addr); - - if(larl[i].result == odtone::mih::link_ac_success){log_(0, " Link Action Success");} - if(larl[i].result == odtone::mih::link_ac_failure){log_(0, " Link Action Failure");} - if(larl[i].result == odtone::mih::link_ac_refused){log_(0, " Link Action Refused");} - if(larl[i].result == odtone::mih::link_ac_incapable){log_(0, " Link Action Incapable");} - - local_link_scan_rsp_list = boost::get<odtone::mih::link_scan_rsp_list>(larl[i].scan_list); - - log_(0, " Link Scan Rsp List - Element: ", local_link_scan_rsp_list.size()); - for(l=0; l<local_link_scan_rsp_list.size(); l++) - { - //link_addr - local_l2_3gpp_3g_cell_id = boost::get<odtone::mih::l2_3gpp_3g_cell_id>(local_link_scan_rsp_list[l].id); - - log_(0, " 3GPP Cell ID Adress: ", local_link_scan_rsp_list.size()); - for(p=0; p<3; p++) { - std::printf("[mih_usr]: "); - std::printf(" Plmn %d: %d", p, local_l2_3gpp_3g_cell_id.plmn_id[p]); - } - log_(0, " Cell-ID: ", (local_l2_3gpp_3g_cell_id._cell_id/); - //net_id network identifier - log_(0, " Network Identifier: "); - std::printf("[mih_usr]: "); - for(n=0; n<local_link_scan_rsp_list[l].net_id.size(); n++) - { - std::printf("%c", local_link_scan_rsp_list[l].net_id[n]); - } - std::printf("\n"); - //sig_strength - local_sig_strength = boost::get<odtone::sint8>(local_link_scan_rsp_list[l].signal); - std::printf("[mih_usr]: "); - std::printf("Signal Strength: %d \n", local_sig_strength); - //log_(0, " Signal Strength: ", local_sig_strength); - } - log_(0, " "); - } -*/ - log_(0, "MIH_Link_Actions.confirm - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Actions_request(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - odtone::mih::link_action_list lal; - odtone::mih::link_action_req link_act_req; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0, ""); - log_(0, "send_MIH_Link_Actions_request - Begin"); - //address UMTS - link_act_req.id.type = rcv_link_id.type; - link_act_req.id.addr = rcv_link_id.addr; - - if(mih_user::link_action_request == 0){ - link_act_req.action.type = odtone::mih::link_ac_type_power_up; - link_act_req.action.attr.set(odtone::mih::link_ac_attr_scan); - //link_act_req.action.param...; - } else if(mih_user::link_action_request == 1) { - link_act_req.action.type = odtone::mih::link_ac_type_power_up; - } else if(mih_user::link_action_request == 2) { - link_act_req.action.type = odtone::mih::link_ac_type_power_down; - } - - link_act_req.ex_time = 0; - - lal.push_back(link_act_req); - - - m << odtone::mih::request(odtone::mih::request::link_actions) - & odtone::mih::tlv_link_action_list(lal); - - - log_(0, "\t- LINK_ID: "); - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(link_act_req.id.addr); - print_l2_3gpp_addr(link_act_req.id.type, local_l2_3gpp_addr); - - log_(0, "\t- Link Actions: " + link_actions_req2string(link_act_req)); - - m.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.destination().to_string() +"][--- MIH_Link_Actions.request\\n"+link_actions_req2string(link_act_req)+" --->]["+msg.source().to_string()+"]\n"); - _mihf.async_send(m, boost::bind(&mih_user::event_handler, this, _1, _2)); - - log_(0, "send_MIH_Link_Actions_request - End"); - log_(0, ""); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Detected_indication(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_det_info_list ldil; - - log_(0, ""); - log_(0, "receive_MIH_Link_Detected_indication - Begin"); - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_det_info_list(ldil); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Detected.indication --->]["+msg.destination().to_string()+"]\n"); - - log_(0, "receive_MIH_Link_Detected_indication - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Get_Parameters_request(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - odtone::mih::dev_states_req dsr; - odtone::uint iter; - - odtone::mih::link_id li; - odtone::mih::link_id_list lil; - - odtone::mih::link_status_req lsr; - - log_(0,""); - log_(0, "send_MIH_Link_Get_Parameters_request - Begin"); - - //set values - dsr.set(odtone::mih::dev_state_device_info); //optional - - li.type = rcv_link_id.type; - li.addr = rcv_link_id.addr; - lil.push_back(li); - odtone::mih::link_param_gen lp1; - //odtone::mih::link_param_gen lp2, lp3, lp4, lp5; - - lp1 = odtone::mih::link_param_gen_data_rate; - lsr._param_type_list.push_back(lp1); - - /*lp2 = odtone::mih::link_param_gen_sinr; - lsr._param_type_list.push_back(lp2); - - lp3 = odtone::mih::link_param_gen_packet_error_rate; - lsr._param_type_list.push_back(lp3); - - lp4 = odtone::mih::link_param_gen_throughput; - lsr._param_type_list.push_back(lp4); - - lp5 = odtone::mih::link_param_gen_signal_strength; - lsr._param_type_list.push_back(lp5);*/ - - lsr._states_req.set(odtone::mih::link_states_req_op_mode); - lsr._states_req.set(odtone::mih::link_states_req_channel_id); - lsr._desc_req.set(odtone::mih::link_desc_req_classes_of_service_supported); - - - m << odtone::mih::request(odtone::mih::request::link_get_parameters) - & odtone::mih::tlv_dev_states_req(dsr) - & odtone::mih::tlv_link_id_list(lil) - & odtone::mih::tlv_get_status_req_set(lsr); - - m.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.destination().to_string() +"][--- MIH_Link_Get_Parameters.request --->]["+msg.source().to_string()+"]\n"); - _mihf.async_send(m, boost::bind(&mih_user::event_handler, this, _1, _2)); - - //log_(0, " - DEVICE STATES REQUEST"); - - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0, "\t- LINK ID LIST - Length: ", lil.size()); - - for(iter=0; iter<lil.size(); iter++) - { - log_(0, "\t LINK ID ", iter); - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(lil[iter].addr); - print_l2_3gpp_addr(lil[iter].type, local_l2_3gpp_addr); - } - - log_(0, "\t- GET STATUS REQUEST "); - if(lsr._states_req.get(odtone::mih::link_states_req_op_mode) == 1) {log_(0, "\t Link power mode requested");} - if(lsr._states_req.get(odtone::mih::link_states_req_channel_id) == 1) {log_(0, "\t Channel identifier requested (as defined in the specific link technology)");} - - if(lp1 == odtone::mih::link_param_gen_data_rate) {log_(0, "\t DATA RATE link parameter requested");} - if(lp1 == odtone::mih::link_param_gen_signal_strength) {log_(0, "\t SIGNAL STRENGTH link parameter is required");} - if(lp1 == odtone::mih::link_param_gen_sinr) {log_(0, "\t SINR link parameter is required");} - if(lp1 == odtone::mih::link_param_gen_throughput) {log_(0, "\t THROUGHPUT link parameter is required");} - - log_(0, "\t- LINK DESCRIPTOR REQUESTED "); - - if(lsr._desc_req.get(odtone::mih::link_desc_req_classes_of_service_supported) == 1) {log_(0, "\t Number of CoS Supported ");} - if(lsr._desc_req.get(odtone::mih::link_desc_req_queues_supported) == 1) {log_(0, "\t Number of Queues Supported ");} - log_(0, "send_MIH_Link_Get_Parameters_request - End"); - log_(0, ""); - -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Get_Parameters_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - - odtone::mih::status st; - odtone::mih::status_rsp_list srl; - - odtone::uint iter; - - log_(0, ""); - log_(0, "receive_MIH_Link_Get_Parameters_confirm - Begin"); - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_get_status_rsp_list(srl); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihfid.to_string() +"][--- MIH_Link_Get_Parameters.confirm\\n"+status2string(st.get()).c_str()+" --->]["+_mihuserid.to_string()+"]\n"); - log_(0, "\t- STATUS: ", status2string(st.get()), " ", st.get()); - - - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0, "\t- STATUS RSP LIST - Length: ", srl.size()); - - for(iter=0; iter<srl.size(); iter++) - { - log_(0, "\t LINK ID ", iter+1, ":"); - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(srl[iter].id.addr); - print_l2_3gpp_addr(srl[iter].id.type, local_l2_3gpp_addr); - log_(0, "\t LINK STATUS RSP List - Element: ", iter+1); - - /*odtone::uint iter1; - - log_(0, " States Rsp List - Length: ", srl[iter].rsp.states_rsp_list.size()); - //States Rsp List (vector) - for(iter1=0; iter1<srl[iter1].rsp.states_rsp_list.size(); iter1++) - { - //each element op_mode or channel_id - log_(0, " Element:", iter1+1, " - Value:", srl[iter1].rsp.states_rsp_list[iter1]); - } - - log_(0, " Param List - Length: ", srl[iter].rsp.param_list.size()); - //Param List - for(iter1=0; iter1<srl[iter1].rsp.param_list.size(); iter1++) - { - //log_(0, "Element:", iter+1, "Type: ", srl[iter1].rsp.param_list[iter1].type ,"Value: ", srl[iter1].rsp.param_list[iter1]); - // 1 - link_param_type - // 2 - boost::variant<link_param_val, qos_param_val> - } - - log_(0, " Desc_rsp_list - Length: ", srl[iter].rsp.desc_rsp_list.size()); - //Desc_rsp_list - for(iter1=0; iter1<srl[iter1].rsp.desc_rsp_list.size(); iter1++) - { - //log_(0, "Element:", iter+1, "Value", srl[iter1].rsp.desc_rsp_list[iter1]); - //boost::variant<num_cos, num_queue> - //uint8 num_cos - uint8 num_queue - }*/ - } - log_(0, "receive_MIH_Link_Get_Parameters_confirm - End"); - -} - - -/** - * Capability Discover handler. - * - * @param msg Received message. - * @param ec Error Code. - */ -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - log_(0, ""); - log_(0, "receive_MIH_Capability_Discover_confirm - Begin"); - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - odtone::mih::status st; - boost::optional<odtone::mih::net_type_addr_list> ntal; - boost::optional<odtone::mih::mih_evt_list> evt; - - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - odtone::mih::link_tuple_id li; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_net_type_addr_list(ntal) - & odtone::mih::tlv_event_list(evt); - // MIH_TRANS_LIST could be added - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihfid.to_string() ,"][--- MIH_Capability_Discover.confirm\\nstatus=", status2string(st.get()).c_str(), - "\\nEvent list=",evt2string(evt.get()).c_str(), - "\\nNet type addr list=" , net_type_addr_list2string(ntal).c_str(), - " --->][",_mihuserid.to_string(),"]\n"); - log_(0, "\t- STATUS: ", status2string(st.get()), " " ,st.get()); - - if (evt) { - log_(0, "\t- MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - - //log_(0, "MIH-User has received a Capability_Discover.response with status ", - // st.get(), " and the following capabilities:"); - - log_(0, "\t- LIST(NET_TYPE_ADDR) - Network Types and Link Address:"); - - if (ntal) { - for (odtone::mih::net_type_addr_list::iterator i = ntal->begin(); i != ntal->end(); ++i) - { - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(i->addr); - li.type = boost::get<odtone::mih::link_type>(i->nettype.link); - - rcv_net_type_addr.addr = boost::get<odtone::mih::l2_3gpp_addr>(i->addr); - rcv_net_type_addr.nettype.link = boost::get<odtone::mih::link_type>(i->nettype.link); - - rcv_link_id.addr = boost::get<odtone::mih::l2_3gpp_addr>(i->addr); - rcv_link_id.type = boost::get<odtone::mih::link_type>(i->nettype.link); - - print_l2_3gpp_addr(li.type, local_l2_3gpp_addr); - // should be the same print - //print_l2_3gpp_addr(rcv_link_id.type, rcv_link_id.addr); - - //log_(0, *i); - } - - } else { - log_(0, "none"); - } - - log_(0, ""); - // - // event subscription - // - // For every interface the MIHF sent in the - // Capability_Discover.response send an Event_Subscribe.request - // for all availabe events - // - if (ntal && evt) { - for (odtone::mih::net_type_addr_list::iterator i = ntal->begin(); i != ntal->end(); ++i) { - odtone::mih::message req; - odtone::mih::link_tuple_id li; - - if (i->nettype.link.which() == 1) - { - li.addr = i->addr; - li.type = boost::get<odtone::mih::link_type>(i->nettype.link); - - req << odtone::mih::request(odtone::mih::request::event_subscribe, _mihfid) - & odtone::mih::tlv_link_identifier(li) - & odtone::mih::tlv_event_list(evt); - - req.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihuserid.to_string() +"][--- MIH_Event_Subscribe.request"+ - "\\nLink="+link_tupple_id2string(li).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - " --->]["+_mihfid.to_string()+"]\n"); - _mihf.async_send(req, boost::bind(&mih_user::receive_MIH_Event_Subscribe_response, this, _1, _2)); - - log_(0, "MIH-User has sent Event_Subscribe.request to ", req.destination().to_string()); - - if (evt) { - log_(0, "\t- MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - } - } - } - log_(0, "receive_MIH_Capability_Discover_confirm - End"); -} - -/** - * Event subscribe handler. - * - * @param msg Received message. - * @param ec Error Code. - */ -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Event_Subscribe_response(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - //log_(0, __FUNCTION__, "(", msg.tid(), ")"); - log_(0, ""); - log_(0, "receive_MIH_Event_Subscribe_response - Begin"); - - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - odtone::mih::status st; - boost::optional<odtone::mih::mih_evt_list> evt; - - msg >> odtone::mih::response() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_event_list(evt); - - if (evt) { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihfid.to_string() +"][--- MIH_Event_Subscribe.response\\nstatus="+ - status2string(st.get()).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - " --->]["+_mihuserid.to_string()+"]\n"); - } else { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihfid.to_string() +"][--- MIH_Event_Subscribe.response\\nstatus="+ - status2string(st.get()).c_str()+ - " --->]["+_mihuserid.to_string()+"]\n"); - } - log_(0, " - STATUS: ", status2string(st.get()), " " ,st.get()); - - mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec); - log_(0, "receive_MIH_Event_Subscribe_response - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Configure_Thresholds_request(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - odtone::mih::threshold th; - std::vector<odtone::mih::threshold> thl; - - odtone::mih::link_tuple_id lti; - odtone::mih::l2_3gpp_addr local_l2_3gpp_addr; - - log_(0,""); - log_(0, "send_MIH_Link_Configure_Thresholds_request - Begin"); - - //link_tuple_id - lti.type = rcv_link_id.type; - lti.addr = rcv_link_id.addr; - - local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(lti.addr); - - //List of the link threshold parameters - odtone::mih::link_cfg_param_list lcpl; - odtone::mih::link_cfg_param lcp; - odtone::mih::link_param_gen lp; - - //link_param_gen_data_rate = 0, /**< Data rate. */ - //link_param_gen_signal_strength = 1, /**< Signal strength. */ - //link_param_gen_sinr = 2, /**< SINR. */ - //link_param_gen_throughput = 3, /**< Throughput. */ - //link_param_gen_packet_error_rate = 4, /**< Packet error rate. */ - lp = odtone::mih::link_param_gen_signal_strength; - - lcp.type = lp; - //th_action_normal = 0, /**< Set normal threshold. */ - //th_action_one_shot = 1, /**< Set one-shot threshold. */ - //th_action_cancel = 2 /**< Cancel threshold. */ - lcp.action = odtone::mih::th_action_one_shot; - - //above_threshold = 0, /**< Above threshold. */ - //below_threshold = 1, /**< Below threshold. */ - if (link_threshold_request == 0) { - th.threshold_val = THRESHOLD_HIGH_VAL; - th.threshold_x_dir = odtone::mih::threshold::above_threshold; - } else if (link_threshold_request == 0) { - th.threshold_val = THRESHOLD_LOW_VAL; - th.threshold_x_dir = odtone::mih::threshold::below_threshold; - } else { - th.threshold_val = THRESHOLD_LOW_VAL; - th.threshold_x_dir = odtone::mih::threshold::below_threshold; - } - - thl.push_back(th); - lcp.threshold_list = thl; - lcpl.push_back(lcp); - - m << odtone::mih::request(odtone::mih::request::link_configure_thresholds) - & odtone::mih::tlv_link_identifier(lti) - & odtone::mih::tlv_link_cfg_param_list(lcpl); - - m.destination(msg.source()); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihuserid.to_string() +"][--- MIH_Link_Configure_Thresholds.request\\nlink="+ - link_tupple_id2string(lti).c_str() + - " --->]["+_mihfid.to_string()+"]\n"); - _mihf.async_send(m, boost::bind(&mih_user::event_handler, this, _1, _2)); - - - log_(0, "\t- LINK TUPLE ID - Network Types and Link Address:"); - print_l2_3gpp_addr(lti.type, local_l2_3gpp_addr); - - log_(0, "\t- LINK CFG PARAM LIST - Length: ", lcpl.size()); - - if(lp == odtone::mih::link_param_gen_data_rate) {log_(0, "\t Generic link parameter DATA RATE ");} - if(lp == odtone::mih::link_param_gen_signal_strength) {log_(0, "\t Generic link parameter SIGNAL STRENGTH");} - if(lp == odtone::mih::link_param_gen_sinr) {log_(0, "\t Generic link parameter SINR");} - if(lp == odtone::mih::link_param_gen_throughput) {log_(0, "\t Generic link parameter THROUGHPUT");} - - if(lcp.action == odtone::mih::th_action_normal) {log_(0, "\t Normal Threshold");} - if(lcp.action == odtone::mih::th_action_one_shot) {log_(0, "\t One Shot Threshold");} - if(lcp.action == odtone::mih::th_action_cancel) {log_(0, "\t Threshold to be canceled");} - - log_(0, "\t Threshold value: ", th.threshold_val); - - if(th.threshold_x_dir == odtone::mih::threshold::below_threshold) {log_(0, "\t Threshold direction BELOW");} - if(th.threshold_x_dir == odtone::mih::threshold::above_threshold) {log_(0, "\t Threshold direction ABOVE");} - - log_(0, "send_MIH_Link_Configure_Thresholds_request - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Configure_Thresholds_confirm(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - log_(0, ""); - log_(0, "receive_MIH_Link_Configure_Thresholds_confirm - Begin"); - - odtone::uint iter; - odtone::mih::status st; - - //boost::optional<odtone::mih::link_cfg_status_list> lcsl; - odtone::mih::link_cfg_status_list lcsl; - odtone::mih::link_cfg_status lcp; - odtone::mih::link_param_gen lp; - - odtone::mih::link_tuple_id lti; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_identifier(lti) - & odtone::mih::tlv_link_cfg_status_list(lcsl); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihfid.to_string() +"][--- MIH_Link_Configure_Thresholds.confirm\\nstatus="+status2string(st.get()).c_str()+" --->]["+_mihuserid.to_string()+"]\n"); - log_(0, "\t- STATUS: ", status2string(st.get()), " " ,st.get()); - - log_(0, "\t- LINK CFG STATUS LIST - Length: ", lcsl.size()); - - for(iter=0; iter<lcsl.size(); iter++) - { - log_(0, "\t Link Param Type: ", lcsl[0].type); - log_(0, "\t Threshold Val: ", (lcsl[0].thold.threshold_val/256)); - if(lcsl[0].thold.threshold_x_dir == odtone::mih::threshold::below_threshold) {log_(0, "\t Threshold direction BELOW");} - if(lcsl[0].thold.threshold_x_dir == odtone::mih::threshold::above_threshold) {log_(0, "\t Threshold direction ABOVE");} - if(lcsl[0].status == odtone::mih::status_success){log_(0, "\t Config Status: Success ");} - else {log_(0, "\t Config Status: ", lcsl[0].status);} - } - - log_(0, "receive_MIH_Link_Configure_Thresholds_confirm - End"); - log_(0,""); -} - -//----------------------------------------------------------------------------- -int main(int argc, char** argv) -//----------------------------------------------------------------------------- -{ - odtone::setup_crash_handler(); - - try { - boost::asio::io_service ios; - - // declare MIH Usr available options - po::options_description desc(odtone::mih::octet_string("MIH Usr Configuration")); - desc.add_options() - ("help", "Display configuration options") - (odtone::sap::kConf_File, po::value<std::string>()->default_value("mih_usr.conf"), "Configuration file") - (odtone::sap::kConf_Receive_Buffer_Len, po::value<uint>()->default_value(4096), "Receive buffer length") - (odtone::sap::kConf_Port, po::value<ushort>()->default_value(1234), "Listening port") - (odtone::sap::kConf_MIH_SAP_id, po::value<std::string>()->default_value("user"), "MIH-User ID") - (kConf_MIH_Commands, po::value<std::string>()->default_value(""), "MIH-User supported commands") - (odtone::sap::kConf_MIHF_Ip, po::value<std::string>()->default_value("127.0.0.1"), "Local MIHF IP address") - (odtone::sap::kConf_MIHF_Local_Port, po::value<ushort>()->default_value(1025), "Local MIHF communication port") - (odtone::sap::kConf_MIH_SAP_dest, po::value<std::string>()->default_value("mihf1"), "MIHF destination"); - - odtone::mih::config cfg(desc); - cfg.parse(argc, argv, odtone::sap::kConf_File); - - if (cfg.help()) { - std::cerr << desc << std::endl; - return EXIT_SUCCESS; - } - - mih_user usr(cfg, ios); - - ios.run(); - - } catch(std::exception& e) { - log_(0, "exception: ", e.what()); - } -} - -// EOF //////////////////////////////////////////////////////////////////////// diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/rg_mih_usr.cpp b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/rg_mih_usr.cpp deleted file mode 100644 index 70808c1f4b..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0/rg_mih_usr.cpp +++ /dev/null @@ -1,1167 +0,0 @@ -//============================================================================== -// Brief : MIH-User -// Authors : Bruno Santos <bsantos@av.it.pt> -//------------------------------------------------------------------------------ -// ODTONE - Open Dot Twenty One -// -// Copyright (C) 2009-2012 Universidade Aveiro -// Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro -// -// This software is distributed under a license. The full license -// agreement can be found in the file LICENSE in this distribution. -// This software may not be copied, modified, sold or distributed -// other than expressed in the named license agreement. -// -// This software is distributed without any warranty. -//============================================================================== - -#include <odtone/base.hpp> -#include <odtone/debug.hpp> -#include <odtone/logger.hpp> -#include <odtone/mih/request.hpp> -#include <odtone/mih/response.hpp> -#include <odtone/mih/indication.hpp> -#include <odtone/mih/confirm.hpp> -#include <odtone/mih/tlv_types.hpp> -#include <odtone/sap/user.hpp> - -#include <boost/utility.hpp> -#include <boost/bind.hpp> -#include <boost/tokenizer.hpp> -#include <boost/foreach.hpp> -#include <boost/format.hpp> - -#include <iostream> -#include <map> -#include <time.h> - -/////////////////////////////////////////////////////////////////////////////// - -// Definition of the scenario to execute -#define NB_OF_RESOURCES 4 // Should not exceed mih_user::_max_link_action_requests -//#define SCENARIO_1 // Sequentially activate and deactivate each resource -#define SCENARIO_2 // Activate all resources, then deactivate all resources - -/////////////////////////////////////////////////////////////////////////////// -// The scenario coded in this MIH-USER is the following (with eRALlteDummy and NASRGDummy executables) -// +--------+ +-----+ -// |MIH_USER| |MIH-F| -// +---+----+ +--+--+ -// | | _current_link_action_request = 0 -// |---------- User_Register.indication ---------------->| (supported_commands) Handler next msg=user_reg_handler -// | | -// |---------- Capability_Discover.request ------------->| Handler next msg=receive_MIH_Capability_Discover_confirm -// |<--------- Capability_Discover.confirm --------------| (success) -// | | -// |---------- Event_Subscribe.request ----------------->| Handler next msg=receive_MIH_Event_Subscribe_confirm -// |<--------- Event_Subscribe.confirm ------------------| (success) -// | | -// ------------------------------------------------------------------------------------------------------------------------ -// Scenario 1: Sequentially activate and deactivate each resource -// ------------------------------------------------------------------------------------------------------------------------ -// | | -// |---------- Link_Actions.request -------------------->| (activate-resources[_current_link_action_request]) -// | | Handler next msg=receive_MIH_Link_Actions_confirm -// |<--------- Link_Actions.confirm ---------------------| (success) -// |---------- Link_Actions.request -------------------->| (deactivate-resources[_current_link_action_request]) -// | | Handler next msg=receive_MIH_Link_Actions_confirm -// | | _current_link_action_request = _current_link_action_request + 1 -// |<--------- Link_Actions.confirm ---------------------| (success) -// | . | -// | . | -// | . | -// | | -// ------------------------------------------------------------------------------------------------------------------------ -// Scenario 2: Activate all resources, then deactivate all resources -// ------------------------------------------------------------------------------------------------------------------------ -// | | -// |---------- Link_Actions.request -------------------->| (activate-resources[_current_link_action_request]) -// | | Handler next msg=receive_MIH_Link_Actions_confirm -// | | _current_link_action_request = _current_link_action_request + 1 -// |<--------- Link_Actions.confirm ---------------------| (success) -// | . | -// | . | -// | . | _current_link_action_request = 0 -// |---------- Link_Actions.request -------------------->| (deactivate-resources[_current_link_action_request]) -// | | Handler next msg=receive_MIH_Link_Actions_confirm -// | | _current_link_action_request = _current_link_action_request + 1 -// |<--------- Link_Actions.confirm ---------------------| (success) -// | . | -// | . | -// | . | -// | | -// ------------------------------------------------------------------------------------------------------------------------ -// | | -// |---------- Event_Unsubscribe.request --------------->| Handler next msg=receive_MIH_Event_Unsubscribe_confirm -// |<--------- Event_Subscribe.confirm ------------------| (success) -// | | -// | | -/////////////////////////////////////////////////////////////////////////////// - -static const char* const kConf_MIH_Commands = "user.commands"; - -/////////////////////////////////////////////////////////////////////////////// - -namespace po = boost::program_options; - -using odtone::uint; -using odtone::ushort; -using odtone::sint8; - -odtone::logger log_("[mih_usr]", std::cout); - -/////////////////////////////////////////////////////////////////////////////// - -//----------------------------------------------------------------------------- -void __trim(odtone::mih::octet_string &str, const char chr) -//----------------------------------------------------------------------------- -{ - str.erase(std::remove(str.begin(), str.end(), chr), str.end()); -} -//----------------------------------------------------------------------------- -template <class T> std::string StringOf(T object) { -//----------------------------------------------------------------------------- - std::ostringstream os; - os << object; - return(os.str()); -} -//----------------------------------------------------------------------------- -std::string getTimeStamp4Log() -//----------------------------------------------------------------------------- -{ - std::stringstream ss (std::stringstream::in | std::stringstream::out); - struct timespec time_spec; - unsigned int time_now_micros; - unsigned int time_now_s; - clock_gettime (CLOCK_REALTIME, &time_spec); - time_now_s = (unsigned int) time_spec.tv_sec % 3600; - time_now_micros = (unsigned int) time_spec.tv_nsec/1000; - ss << time_now_s << ':' << time_now_micros; - return ss.str(); -} -//----------------------------------------------------------------------------- -std::string status2string(odtone::mih::status statusP){ -//----------------------------------------------------------------------------- - switch (statusP.get()) { - case odtone::mih::status_success: return "SUCCESS";break; - case odtone::mih::status_failure: return "UNSPECIFIED_FAILURE";break; - case odtone::mih::status_rejected: return "REJECTED";break; - case odtone::mih::status_authorization_failure: return "AUTHORIZATION_FAILURE";break; - case odtone::mih::status_network_error: return "NETWORK_ERROR";break; - default: return "UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string link_down_reason2string(odtone::mih::link_dn_reason reasonP){ -//----------------------------------------------------------------------------- - switch (reasonP.get()) { - case odtone::mih::link_dn_reason_explicit_disconnect: return "DN_REASON_EXPLICIT_DISCONNECT";break; - case odtone::mih::link_dn_reason_packet_timeout: return "DN_REASON_PACKET_TIMEOUT";break; - case odtone::mih::link_dn_reason_no_resource: return "DN_REASON_NO_RESOURCE";break; - case odtone::mih::link_dn_reason_no_broadcast: return "DN_REASON_NO_BROADCAST";break; - case odtone::mih::link_dn_reason_authentication_failure: return "DN_REASON_AUTHENTICATION_FAILURE";break; - case odtone::mih::link_dn_reason_billing_failure: return "DN_REASON_BILLING_FAILURE";break; - default: return "DN_REASON_UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string link_going_down_reason2string(odtone::mih::link_gd_reason reasonP){ -//----------------------------------------------------------------------------- - switch (reasonP.get()) { - case odtone::mih::link_gd_reason_explicit_disconnect: return "GD_REASON_EXPLICIT_DISCONNECT";break; - case odtone::mih::link_gd_reason_link_parameter_degrading: return "GD_REASON_PARAMETER_DEGRADING";break; - case odtone::mih::link_gd_reason_low_power: return "GD_REASON_LOW_POWER";break; - case odtone::mih::link_gd_reason_no_resource: return "GD_REASON_NO_RESOURCE";break; - default: return "GD_REASON_UNKNOWN"; - } -} -//----------------------------------------------------------------------------- -std::string evt2string(odtone::mih::mih_evt_list evtP){ -//----------------------------------------------------------------------------- - std::string s; - if(evtP.get(odtone::mih::mih_evt_link_detected)) s = std::string("DETECTED "); - if(evtP.get(odtone::mih::mih_evt_link_up)) s += "UP "; - if(evtP.get(odtone::mih::mih_evt_link_down)) s += "DOWN "; - if(evtP.get(odtone::mih::mih_evt_link_parameters_report)) s += "PARAMETERS_REPORT "; - if(evtP.get(odtone::mih::mih_evt_link_going_down)) s += "GOING_DOWN "; - if(evtP.get(odtone::mih::mih_evt_link_handover_imminent)) s += "HANDOVER_IMMINENT "; - if(evtP.get(odtone::mih::mih_evt_link_handover_complete)) s += "HANDOVER_COMPLETE "; - if(evtP.get(odtone::mih::mih_evt_link_pdu_transmit_status)) s += "PDU_TRANSMIT_STATUS "; - return s; -} -//----------------------------------------------------------------------------- -std::string cmd2string(odtone::mih::mih_cmd_list cmdP){ -//----------------------------------------------------------------------------- - std::string s; - if(cmdP.get(odtone::mih::mih_cmd_link_get_parameters)) s = std::string("Link_Get_Parameters "); - if(cmdP.get(odtone::mih::mih_cmd_link_configure_thresholds)) s += "Link_Configure_Thresholds "; - if(cmdP.get(odtone::mih::mih_cmd_link_actions)) s += "Link_Actions "; - if(cmdP.get(odtone::mih::mih_cmd_net_ho_candidate_query)) s += "Net_HO_Candidate_Query "; - if(cmdP.get(odtone::mih::mih_cmd_net_ho_commit)) s += "Net_HO_Commit "; - if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_query_resources)) s += "N2N_HO_Query_Resources "; - if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_commit)) s += "N2N_HO_Commit "; - if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_complete)) s += "N2N_HO_Complete "; - if(cmdP.get(odtone::mih::mih_cmd_mn_ho_candidate_query)) s += "MN_HO_Candidate_Query "; - if(cmdP.get(odtone::mih::mih_cmd_mn_ho_commit)) s += "MN_HO_Commit "; - if(cmdP.get(odtone::mih::mih_cmd_mn_ho_complete)) s += "MN_HO_Complete "; - return s; -} -//----------------------------------------------------------------------------- -std::string link_type2string(const odtone::mih::link_type& lt) -//----------------------------------------------------------------------------- -{ - switch (lt.get()) { - case odtone::mih::link_type_gsm: return "GSM"; break; - case odtone::mih::link_type_gprs: return "GPRS"; break; - case odtone::mih::link_type_edge: return "EDGE"; break; - case odtone::mih::link_type_ethernet: return "Ethernet"; break; - case odtone::mih::link_type_wireless_other: return "Other"; break; - case odtone::mih::link_type_802_11: return "IEEE 802.11"; break; - case odtone::mih::link_type_cdma2000: return "CDMA-2000"; break; - case odtone::mih::link_type_umts: return "UMTS"; break; - case odtone::mih::link_type_cdma2000_hrpd: return "CDMA-2000-HRPD"; break; - case odtone::mih::link_type_lte: return "LTE"; break; - case odtone::mih::link_type_802_16: return "IEEE 802.16"; break; - case odtone::mih::link_type_802_20: return "IEEE 802.20"; break; - case odtone::mih::link_type_802_22: return "IEEE 802.22"; break; - default: break; - } - return "Unknown link type"; -} -//----------------------------------------------------------------------------- -std::string link_addr2string(const odtone::mih::link_addr *addr) -//----------------------------------------------------------------------------- -{ - if (const odtone::mih::mac_addr *la = boost::get<odtone::mih::mac_addr>(addr)) { - return la->address(); - } - else if (const odtone::mih::l2_3gpp_3g_cell_id *la = boost::get<odtone::mih::l2_3gpp_3g_cell_id>(addr)) { - char plmn[16]; - sprintf(plmn, "%hhx:%hhx:%hhx", la->plmn_id[0], la->plmn_id[1], la->plmn_id[2]); - return str(boost::format("%s %d") % plmn % la->_cell_id); - } - else if (const odtone::mih::l2_3gpp_2g_cell_id *la = boost::get<odtone::mih::l2_3gpp_2g_cell_id>(addr)) { - char plmn[16]; - sprintf(plmn, "%hhx:%hhx:%hhx", la->plmn_id[0], la->plmn_id[1], la->plmn_id[2]); - return str(boost::format("%s %d %d") % plmn % la->_lac % la->_ci); - } - else if (const odtone::mih::l2_3gpp_addr *la = boost::get<odtone::mih::l2_3gpp_addr>(addr)) { - return la->value; - } - else if (const odtone::mih::l2_3gpp2_addr *la = boost::get<odtone::mih::l2_3gpp2_addr>(addr)) { - return la->value; - } - else if (const odtone::mih::other_l2_addr *la = boost::get<odtone::mih::other_l2_addr>(addr)) { - return la->value; - } - return "null"; -} -//----------------------------------------------------------------------------- -std::string l2_3gpp_3g_cell_id2string(odtone::mih::l2_3gpp_3g_cell_id& addr) -//----------------------------------------------------------------------------- -{ - char buffer[256]; - int index = 0; - - index += std::sprintf(&buffer[index], "plmn: -%hhx--%hhx--%hhx-\n", addr.plmn_id[0], addr.plmn_id[1], addr.plmn_id[2]); - index += std::sprintf(&buffer[index], "cell_id: %hhx\n", addr._cell_id); - return buffer; -} -//----------------------------------------------------------------------------- -std::string link_id2string(odtone::mih::link_id linkP) -//----------------------------------------------------------------------------- -{ - std::string s; - s = link_type2string(linkP.type.get()) + " " + link_addr2string(&linkP.addr); - return s; -} -//----------------------------------------------------------------------------- -std::string ip_addr2string(odtone::mih::ip_addr ip_addrP) { -//----------------------------------------------------------------------------- - std::string s; - switch (ip_addrP.type()) { - case odtone::mih::ip_addr::ipv4: s = "ipv4 "; break; - case odtone::mih::ip_addr::ipv6: s = "ipv6 "; break; - default: s = "Unkown type "; - } - s += ip_addrP.address(); - return s; -} -//----------------------------------------------------------------------------- -std::string ip_tuple2string(odtone::mih::ip_tuple ip_tupleP) { -//----------------------------------------------------------------------------- - char buffer[128]; - std::snprintf(buffer, 128, "%s/%d", ip_addr2string(ip_tupleP.ip).c_str(), ip_tupleP.port_val); - return buffer; -} -//----------------------------------------------------------------------------- -std::string ip_proto2string(odtone::mih::proto ip_protoP) { -//----------------------------------------------------------------------------- - switch (ip_protoP.get()) { - case odtone::mih::proto_tcp: return "TCP"; - case odtone::mih::proto_udp: return "UDP"; - default: break; - } - return "Unknown IP protocol"; -} -// TEMP : next 2 functions are commented to restore flow_id as a uint32 -// full structure will be updated later -/*//----------------------------------------------------------------------------- -std::string flow_id2string(odtone::mih::flow_id flowP) { -//----------------------------------------------------------------------------- - std::string s; - odtone::mih::ip_tuple ip; - ip = flowP.src; - s = "SRC = " + ip_tuple2string(flowP.src); - s += ", DST = " + ip_tuple2string(flowP.dst); - s += ", PROTO = " + ip_proto2string(flowP.transport); - return s; -} -//----------------------------------------------------------------------------- -std::string flow_id2string(odtone::mih::link_ac_param link_ac_paramP) { -//----------------------------------------------------------------------------- - if (odtone::mih::resource_desc *res = boost::get<odtone::mih::resource_desc>(&link_ac_paramP.param)) { - return flow_id2string(res->fid); - } - else if (odtone::mih::flow_attribute *flow = boost::get<odtone::mih::flow_attribute>(&link_ac_paramP.param)) { - return flow_id2string(flow->id); - } - return "null"; -}*/ -//----------------------------------------------------------------------------- -std::string link_ac_result2string(odtone::mih::link_ac_result resultP) -//----------------------------------------------------------------------------- -{ - switch (resultP.get()) { - case odtone::mih::link_ac_success: return "SUCCESS"; break; - case odtone::mih::link_ac_failure: return "FAILURE"; break; - case odtone::mih::link_ac_refused: return "REFUSED"; break; - case odtone::mih::link_ac_incapable: return "INCAPABLE"; break; - default: break; - } - return "Unknown action result"; -} -//----------------------------------------------------------------------------- -std::string link_actions_req2string(odtone::mih::link_action_req link_act_reqP) { -//----------------------------------------------------------------------------- - std::string s; - - s = link_id2string(link_act_reqP.id); - - if(link_act_reqP.action.type == odtone::mih::link_ac_type_none) s += ", AC_TYPE_NONE"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_disconnect) s += ", AC_TYPE_DISCONNECT"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_low_power) s += ", AC_TYPE_LOW_POWER"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_down) s += ", AC_TYPE_POWER_DOWN"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_up) s += ", AC_TYPE_POWER_UP"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_flow_attr) s += ", AC_TYPE_FLOW_ATTR"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_activate_resources) s += ", AC_TYPE_ACTIVATE_RESOURCES"; - if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_deactivate_resources) s += ", AC_TYPE_DEACTIVATE_RESOURCES"; - - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_data_fwd_req)) s += ", AC_ATTR_DATA_FWD_REQ"; - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_scan)) s += ", AC_ATTR_SCAN"; - if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_res_retain)) s += ", AC_ATTR_RES_RETAIN"; - - s += ", " + StringOf(link_act_reqP.ex_time) + " ms"; - return s; -} -//----------------------------------------------------------------------------- -std::string net_type_addr_list2string(boost::optional<odtone::mih::net_type_addr_list> ntalP) { -//----------------------------------------------------------------------------- - std::string s; - odtone::mih::link_id link_id; - - for (odtone::mih::net_type_addr_list::iterator i = ntalP->begin(); i != ntalP->end(); i++) - { - link_id.type = boost::get<odtone::mih::link_type>(i->nettype.link); - link_id.addr = i->addr; - if (i != ntalP->begin()) { - s += " / "; - } - s += link_id2string(link_id); - } - - return s; -} - -/** - * Parse supported commands. - * - * @param cfg Configuration options. - * @return An optional list of supported commands. - */ -boost::optional<odtone::mih::mih_cmd_list> parse_supported_commands(const odtone::mih::config &cfg) -{ - using namespace boost; - - odtone::mih::mih_cmd_list commands; - - std::map<std::string, odtone::mih::mih_cmd_list_enum> enum_map; - enum_map["mih_link_get_parameters"] = odtone::mih::mih_cmd_link_get_parameters; - enum_map["mih_link_configure_thresholds"] = odtone::mih::mih_cmd_link_configure_thresholds; - enum_map["mih_link_actions"] = odtone::mih::mih_cmd_link_actions; - enum_map["mih_net_ho_candidate_query"] = odtone::mih::mih_cmd_net_ho_candidate_query; - enum_map["mih_net_ho_commit"] = odtone::mih::mih_cmd_net_ho_commit; - enum_map["mih_n2n_ho_query_resources"] = odtone::mih::mih_cmd_n2n_ho_query_resources; - enum_map["mih_n2n_ho_commit"] = odtone::mih::mih_cmd_n2n_ho_commit; - enum_map["mih_n2n_ho_complete"] = odtone::mih::mih_cmd_n2n_ho_complete; - enum_map["mih_mn_ho_candidate_query"] = odtone::mih::mih_cmd_mn_ho_candidate_query; - enum_map["mih_mn_ho_commit"] = odtone::mih::mih_cmd_mn_ho_commit; - enum_map["mih_mn_ho_complete"] = odtone::mih::mih_cmd_mn_ho_complete; - - std::string tmp = cfg.get<std::string>(kConf_MIH_Commands); - __trim(tmp, ' '); - - char_separator<char> sep1(","); - tokenizer< char_separator<char> > list_tokens(tmp, sep1); - - BOOST_FOREACH(std::string str, list_tokens) { - if(enum_map.find(str) != enum_map.end()) { - commands.set((odtone::mih::mih_cmd_list_enum) enum_map[str]); - } - } - - return commands; -} - -/////////////////////////////////////////////////////////////////////////////// -/** - * This class provides an implementation of an IEEE 802.21 MIH-User. - */ -class mih_user : boost::noncopyable { -public: - /** - * Construct the MIH-User. - * - * @param cfg Configuration options. - * @param io The io_service object that the MIH-User will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io); - - /** - * Destruct the MIH-User. - */ - ~mih_user(); - -protected: - /** - * User registration handler. - * - * @param cfg Configuration options. - * @param ec Error Code. - */ - void user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec); - /** - * Default MIH event handler. - * - * @param msg Received event notification. - * @param ec Error code. - */ - void event_handler(odtone::mih::message& msg, const boost::system::error_code& ec); - /** - * MIH receive message handler. - * - * @param msg Received message. - * @param ec Error code. - */ - void receive_handler(odtone::mih::message& msg, const boost::system::error_code& ec); - - void send_MIH_User_Register_indication(const odtone::mih::config& cfg); - - void send_MIH_Capability_Discover_request(void); - void receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg); - - void send_MIH_Event_Subscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt); - void receive_MIH_Event_Subscribe_confirm(odtone::mih::message& msg); - - void send_MIH_Event_Unsubscribe_request(void); - void send_MIH_Event_Unsubscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt); - void receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg); - - void send_MIH_Link_Actions_request(const odtone::mih::link_id& link, odtone::mih::link_ac_type type); - void receive_MIH_Link_Actions_confirm(odtone::mih::message& msg); - -private: - odtone::sap::user _mihf; /**< User SAP helper. */ - odtone::mih::id _mihfid; /**< MIHF destination ID. */ - odtone::mih::id _mihuserid; /**< MIH_USER ID. */ - - odtone::mih::ip_addr _mihf_ip; /**< MIHF IP address */ - odtone::mih::port _mihf_lport; /**< MIHF local port number */ - - odtone::mih::link_id_list _link_id_list; /**< List of network link identifiers */ - odtone::mih::mih_evt_list _subs_evt_list; /**< List of subscribed link events */ - - odtone::mih::link_ac_type _last_link_action_type; - odtone::uint _current_link_action_request, _nb_of_link_action_requests; - static const odtone::uint _max_link_action_requests = 4; - - void receive_MIH_Link_Detected_indication(odtone::mih::message& msg); - - void receive_MIH_Link_Up_indication(odtone::mih::message& msg); - - void receive_MIH_Link_Down_indication(odtone::mih::message& msg); - - void receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg); - -}; - -//----------------------------------------------------------------------------- -mih_user::mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io) - : _mihf(cfg, io, boost::bind(&mih_user::event_handler, this, _1, _2)), - _last_link_action_type(odtone::mih::link_ac_type_none), - _current_link_action_request(0), _nb_of_link_action_requests(NB_OF_RESOURCES) -//----------------------------------------------------------------------------- -{ - odtone::mih::octet_string user_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_id); - _mihuserid.assign(user_id.c_str()); - - odtone::mih::octet_string dest_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_dest); - _mihfid.assign(dest_id.c_str()); - - odtone::mih::octet_string src = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIHF_Ip); - boost::asio::ip::address ip = boost::asio::ip::address::from_string(src); - if (ip.is_v4()) { - odtone::mih::ip_addr ip_addr(odtone::mih::ip_addr::ipv4, src); - _mihf_ip = ip_addr; - } - else if (ip.is_v6()) { - odtone::mih::ip_addr ip_addr(odtone::mih::ip_addr::ipv6, src); - _mihf_ip = ip_addr; - } - - _mihf_lport = cfg.get<odtone::mih::port>(odtone::sap::kConf_MIHF_Local_Port); - - //_nb_of_link_action_requests = NB_OF_RESOURCES; - if (_nb_of_link_action_requests > _max_link_action_requests) { - _nb_of_link_action_requests = _max_link_action_requests; - } - - _link_id_list.clear(); - _subs_evt_list.clear(); - - log_(0, "[MSC_NEW]["+getTimeStamp4Log()+"][MIH-USER="+_mihuserid.to_string()+"]\n"); - - // Send MEDIEVAL specific MIH_User_Register.indication message to the MIH-F - mih_user::send_MIH_User_Register_indication(cfg); -} - -//----------------------------------------------------------------------------- -mih_user::~mih_user() -//----------------------------------------------------------------------------- -{ -} - -//----------------------------------------------------------------------------- -void mih_user::user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH-User register result: ", ec.message(), "\n"); - - // - // Let's fire a capability discover request to get things moving - // - mih_user::send_MIH_Capability_Discover_request(); -} - -//----------------------------------------------------------------------------- -void mih_user::event_handler(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - switch (msg.mid()) { - case odtone::mih::indication::link_detected: - mih_user::receive_MIH_Link_Detected_indication(msg); - break; - - case odtone::mih::indication::link_up: - mih_user::receive_MIH_Link_Up_indication(msg); - break; - - case odtone::mih::indication::link_down: - mih_user::receive_MIH_Link_Down_indication(msg); - break; - - case odtone::mih::indication::link_going_down: - mih_user::receive_MIH_Link_Going_Down_indication(msg); - break; - - case odtone::mih::indication::link_handover_imminent: - log_(0, "MIH-User has received a local event \"link_handover_imminent\""); - break; - - case odtone::mih::indication::link_handover_complete: - log_(0, "MIH-User has received a local event \"link_handover_complete\""); - break; - - case odtone::mih::indication::link_parameters_report: - log_(0, "MIH-User has received a local event \"link_parameters_report\""); - break; - - case odtone::mih::indication::link_pdu_transmit_status: - log_(0, "MIH-User has received a local event \"link_pdu_transmit_status\""); - break; - - default: - log_(0, "MIH-User has received UNKNOWN local event"); - break; - } -} - -//----------------------------------------------------------------------------- -void mih_user::receive_handler(odtone::mih::message& msg, const boost::system::error_code& ec) -//----------------------------------------------------------------------------- -{ - if (ec) { - log_(0, __FUNCTION__, " error: ", ec.message()); - return; - } - - switch (msg.mid()) { - - case odtone::mih::confirm::capability_discover: - mih_user::receive_MIH_Capability_Discover_confirm(msg); - break; - - case odtone::mih::confirm::event_subscribe: - mih_user::receive_MIH_Event_Subscribe_confirm(msg); - break; - - case odtone::mih::confirm::event_unsubscribe: - mih_user::receive_MIH_Event_Unsubscribe_confirm(msg); - break; - - case odtone::mih::confirm::link_actions: - mih_user::receive_MIH_Link_Actions_confirm(msg); - break; - - default: - log_(0, "MIH-User has received UNKNOWN message (", msg.mid(), ")\n"); - break; - } -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Detected_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Detected.indication - RECEIVED - Begin\n"); - - odtone::mih::link_det_info_list ldil; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_det_info_list(ldil); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Detected.indication --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - // TODO: for each link_det_info in the list {display LINK_DET_INFO} - - log_(0, "MIH_Link_Detected.indication - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Up_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Up.indication - RECEIVED - Begin\n"); - - odtone::mih::link_tuple_id link; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Up.indication --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str(), "\n"); - - log_(0, "MIH_Link_Up.indication - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Down_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Down.indication - RECEIVED - Begin\n"); - - odtone::mih::link_tuple_id link; - odtone::mih::link_dn_reason ldr; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_link_dn_reason(ldr); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Down.indication\\n"+link_down_reason2string(ldr).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str()); - log_(0, " - LINK_DN_REASON - Link down reason: ", link_down_reason2string(ldr).c_str(), "\n"); - - log_(0, "MIH_Link_Down.indication - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Going_Down.indication - RECEIVED - Begin\n"); - - odtone::mih::link_tuple_id link; - odtone::mih::link_gd_reason lgd; - odtone::mih::link_ac_ex_time ex_time; - - msg >> odtone::mih::indication() - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_time_interval(ex_time) - & odtone::mih::tlv_link_gd_reason(lgd); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Going_Down.indication\\n"+link_going_down_reason2string(lgd).c_str()+" --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str()); - log_(0, " - Time Interval:", (ex_time/256)); - log_(0, " - LINK_GD_REASON - Link going down reason: ", link_going_down_reason2string(lgd).c_str(), "\n"); - - log_(0, "MIH_Link_Going_Down.indication - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_User_Register_indication(const odtone::mih::config& cfg) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - boost::optional<odtone::mih::mih_cmd_list> supp_cmd = parse_supported_commands(cfg); - - m << odtone::mih::indication(odtone::mih::indication::user_register) - & odtone::mih::tlv_command_list(supp_cmd); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_User_Register.indication --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::user_reg_handler, this, boost::cref(cfg), _2)); - - log_(0, "MIH_User_Register.indication - SENT (towards its local MIHF)\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Capability_Discover_request(void) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - m << odtone::mih::request(odtone::mih::request::capability_discover); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Capability_Discover.request --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH_Capability_Discover.request - SENT (towards its local MIHF)\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Capability_Discover.confirm - RECEIVED - Begin\n"); - - odtone::mih::status st; - boost::optional<odtone::mih::net_type_addr_list> ntal; - boost::optional<odtone::mih::mih_evt_list> evt; - boost::optional<odtone::mih::mih_cmd_list> cmd; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_net_type_addr_list(ntal) - & odtone::mih::tlv_event_list(evt) - & odtone::mih::tlv_command_list(cmd); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Capability_Discover.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - "\\nNet type addr list=" + net_type_addr_list2string(ntal).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - if (evt) { - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - if (cmd) { - log_(0, " - MIH_CMD_LIST - Command List: ", cmd2string(cmd.get()).c_str()); - } - if (ntal) { - log_(0, " - LIST(NET_TYPE_ADDR) - Network Types and Link Address: ", net_type_addr_list2string(ntal).c_str()); - } - log_(0, ""); - - // - // event subscription - // - // For every interface the MIHF sent in the - // Capability_Discover.response send an Event_Subscribe.request - // for all availabe events - // - if (ntal && evt) { - _subs_evt_list = evt.get(); // save the list of subscribed link events - for (odtone::mih::net_type_addr_list::iterator i = ntal->begin(); i != ntal->end(); i++) { - if (i->nettype.link.which() == 1) - { - odtone::mih::link_tuple_id li; - - li.addr = i->addr; - li.type = boost::get<odtone::mih::link_type>(i->nettype.link); - _link_id_list.push_back(li); // save the link identifier of the network interface - - mih_user::send_MIH_Event_Subscribe_request(li, evt.get()); - } - } - } - - log_(0, "MIH_Capability_Discover.confirm - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Event_Subscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - m << odtone::mih::request(odtone::mih::request::event_subscribe) - & odtone::mih::tlv_link_identifier(li) - & odtone::mih::tlv_event_list(evt); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Event_Subscribe.request"+ - "\\nLink="+link_id2string(li).c_str()+ - "\\nEvent list="+evt2string(evt).c_str()+ - " --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH-User has sent Event_Subscribe.request to ", m.destination().to_string()); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(li).c_str()); - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt).c_str(), "\n"); - - log_(0, "MIH_Event_Subscribe.request - SENT\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Event_Subscribe_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Event_Subscribe.confirm(", msg.tid(), ") - RECEIVED - Begin\n"); - - odtone::mih::status st; - odtone::mih::link_tuple_id link; - boost::optional<odtone::mih::mih_evt_list> evt; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_event_list(evt); - - if (evt) { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Subscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } else { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Subscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(link).c_str()); - if (evt) { - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - log_(0, ""); - - mih_user::send_MIH_Link_Actions_request(link, odtone::mih::link_ac_type_link_activate_resources); - - log_(0, "MIH_Event_Subscribe.confirm - End\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Event_Unsubscribe_request(void) -//----------------------------------------------------------------------------- -{ - odtone::mih::link_tuple_id li; - - // For every interface the MIH user received in the - // Capability_Discover.confirm, send an Event_Unsubscribe.request - // for all subscribed events - for (odtone::mih::link_id_list::iterator i = _link_id_list.begin(); i != _link_id_list.end(); i++) { - li.type = i->type; - li.addr = i->addr; - mih_user::send_MIH_Event_Unsubscribe_request(li, _subs_evt_list); - } -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Event_Unsubscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - - m << odtone::mih::request(odtone::mih::request::event_unsubscribe) - & odtone::mih::tlv_link_identifier(li) - & odtone::mih::tlv_event_list(evt); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Event_Unsubscribe.request"+ - "\\nLink="+link_id2string(li).c_str()+ - "\\nEvent list="+evt2string(evt).c_str()+ - " --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH-User has sent Event_Unsubscribe.request to ", m.destination().to_string()); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(li).c_str()); - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt).c_str(), "\n"); - - log_(0, "MIH_Event_Unsubscribe.request - SENT\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Event_Unsubscribe.confirm(", msg.tid(), ") - RECEIVED - Begin\n"); - - odtone::mih::status st; - odtone::mih::link_tuple_id link; - boost::optional<odtone::mih::mih_evt_list> evt; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_identifier(link) - & odtone::mih::tlv_event_list(evt); - - if (evt) { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Unsubscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - "\\nEvent list="+evt2string(evt.get()).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } else { - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Unsubscribe.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - "\\nLink="+link_id2string(link).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - } - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - log_(0, " - LINK_TUPLE_ID - Link identifier: ", link_id2string(link).c_str()); - if (evt) { - log_(0, " - MIH_EVT_LIST - Event List: ", evt2string(evt.get()).c_str()); - } - log_(0, ""); - - log_(0, "MIH_Event_Unsubscribe.confirm - End"); -} - -//----------------------------------------------------------------------------- -void mih_user::send_MIH_Link_Actions_request(const odtone::mih::link_id& link, odtone::mih::link_ac_type type) -//----------------------------------------------------------------------------- -{ - odtone::mih::message m; - odtone::mih::link_action_list lal; - odtone::mih::link_action_req link_act_req; - - link_act_req.id = link; - link_act_req.action.type = type; - - _last_link_action_type = type; - - // Initialize resource parameters - odtone::mih::resource_desc res; - - res.lid = link; // Link identifier - res.data_rate = 128000; // bit rate - res.jumbo = false; // jumbo disable - res.multicast = false; // multicast disable - - odtone::mih::qos qos; // Class Of Service - qos.value = 56; - res.qos_val = qos; - res.fid = 555; - -// // Flow identifier -// res.fid.src.ip = _mihf_ip; -// res.fid.src.port_val = _mihf_lport; -// -// if (mih_user::_current_link_action_request == 0) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "2001:0660:0382:0014:0335:0600:8014:9150"); // DUMMY -// } -// else if (mih_user::_current_link_action_request == 1) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "2001:0660:0382:0014:0335:0600:8014:9151"); // DUMMY -// } -// else if (mih_user::_current_link_action_request == 2) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "FF3E:0020:2001:0DB8:0000:0000:0000:0043"); // DUMMY -// res.multicast = true; -// } -// else if (mih_user::_current_link_action_request == 3) { -// res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6, -// "2001:0660:0382:0014:0335:0600:8014:9153"); // DUMMY -// } -// res.fid.dst.port_val = 1235; // DUMMY -// res.fid.transport = odtone::mih::proto_udp; - - link_act_req.action.param.param = res; - - link_act_req.ex_time = 0; - - lal.push_back(link_act_req); - - m << odtone::mih::request(odtone::mih::request::link_actions) - & odtone::mih::tlv_link_action_list(lal); - m.source(_mihuserid); - m.destination(_mihfid); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Link_Actions.request\\n"+link_actions_req2string(link_act_req)+" --->]["+m.destination().to_string()+"]\n"); - - _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2)); - - log_(0, "MIH-User has sent Link_Actions.request to ", m.destination().to_string()); - log_(0, " - LINK_ID - Link identifier: ", link_id2string(link).c_str()); - log_(0, " - FLOW_ID - Flow identifier: ", res.fid); -//TEMP log_(0, " - FLOW_ID - Flow identifier: ", flow_id2string(link_act_req.action.param).c_str()); - log_(0, " - LINK_ACTIONS - Link Actions: " + link_actions_req2string(link_act_req) + "\n"); - - log_(0, "MIH_Link_Actions.request - SENT\n"); -} - -//----------------------------------------------------------------------------- -void mih_user::receive_MIH_Link_Actions_confirm(odtone::mih::message& msg) -//----------------------------------------------------------------------------- -{ - log_(0, "MIH_Link_Actions.confirm - RECEIVED - Begin\n"); - - odtone::mih::status st; - boost::optional<odtone::mih::link_action_rsp_list> larl; - - msg >> odtone::mih::confirm() - & odtone::mih::tlv_status(st) - & odtone::mih::tlv_link_action_rsp_list(larl); - - log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Actions.confirm"+ - "\\nstatus="+status2string(st).c_str()+ - " --->]["+msg.destination().to_string()+"]\n"); - - // Display message parameters - log_(0, " - STATUS: ", status2string(st).c_str(), " (", st.get(), ")"); - if (larl) { - log_(0, " - LINK ACTION RSP LIST - Length:", larl.get().size()); - for (odtone::mih::link_action_rsp_list::iterator i = larl->begin(); i != larl->end(); i++) - { - log_(0, "\tLINK_ID: ", link_id2string(i->id).c_str(), - ", LINK_AC_RESULT: ", link_ac_result2string(i->result).c_str()); - } - } - log_(0, ""); - - // 1st scenario: Sequentially activate and deactivate each resource -#ifdef SCENARIO_1 - if (larl) { - odtone::mih::link_action_rsp *rsp = &larl->front(); - if (_current_link_action_request < _nb_of_link_action_requests) { - if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) { - if (rsp->result.get() == odtone::mih::link_ac_success) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources); - _current_link_action_request += 1; - } - } - else if (_last_link_action_type == odtone::mih::link_ac_type_link_deactivate_resources) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_activate_resources); - } - } - else { // Ends the scenario - mih_user::send_MIH_Event_Unsubscribe_request(); - } - } -#endif // SCENARIO_1 - -#ifdef SCENARIO_2 - // 2nd scenario: Activate all resources, then deactivate all resources - if (larl.get().size() > 0) { - odtone::mih::link_action_rsp *rsp = &larl->front(); - if (++_current_link_action_request < _nb_of_link_action_requests) { - if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_activate_resources); - } - else if (_last_link_action_type == odtone::mih::link_ac_type_link_deactivate_resources) { - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources); - } - } - else if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) { - _current_link_action_request = 0; - mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources); - } - else { // Ends the scenario - mih_user::send_MIH_Event_Unsubscribe_request(); - } - } -#endif // SCENARIO_2 - - log_(0, "MIH_Link_Actions.confirm - End\n"); -} - -//----------------------------------------------------------------------------- -int main(int argc, char** argv) -//----------------------------------------------------------------------------- -{ - odtone::setup_crash_handler(); - - try { - boost::asio::io_service ios; - - // declare MIH Usr available options - po::options_description desc(odtone::mih::octet_string("MIH Usr Configuration")); - desc.add_options() - ("help", "Display configuration options") - (odtone::sap::kConf_File, po::value<std::string>()->default_value("mih_usr.conf"), "Configuration file") - (odtone::sap::kConf_Receive_Buffer_Len, po::value<uint>()->default_value(4096), "Receive buffer length") - (odtone::sap::kConf_Port, po::value<ushort>()->default_value(1234), "Listening port") - (odtone::sap::kConf_MIH_SAP_id, po::value<std::string>()->default_value("user"), "MIH-User ID") - (kConf_MIH_Commands, po::value<std::string>()->default_value(""), "MIH-User supported commands") - (odtone::sap::kConf_MIHF_Ip, po::value<std::string>()->default_value("127.0.0.1"), "Local MIHF IP address") - (odtone::sap::kConf_MIHF_Local_Port, po::value<ushort>()->default_value(1025), "Local MIHF communication port") - (odtone::sap::kConf_MIH_SAP_dest, po::value<std::string>()->default_value("mihf1"), "MIHF destination"); - - odtone::mih::config cfg(desc); - cfg.parse(argc, argv, odtone::sap::kConf_File); - - if (cfg.help()) { - std::cerr << desc << std::endl; - return EXIT_SUCCESS; - } - - mih_user usr(cfg, ios); - - ios.run(); - - } catch(std::exception& e) { - log_(0, "exception: ", e.what()); - } -} - -// EOF //////////////////////////////////////////////////////////////////////// - diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/sendUDP-01 b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/sendUDP-01 deleted file mode 100755 index d50c3d3a10c1856f63a2628cd3db6c75c0ede4bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12329 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 IISa-A0PcaoUjP6A diff --git a/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/sendUDP-FF b/openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/sendUDP-FF deleted file mode 100755 index 84d4f1246fa41f9b90397ff1a1a6d2d037074b69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12329 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 Hvrzmmzna2b diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_action.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_action.h deleted file mode 100644 index fbb4e82d7c..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_action.h +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file eRALlte_action.h - * \brief - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __RAL_LTE_ACTION_H__ -#define __RAL_LTE_ACTION_H__ - -#include "MIH_C_msg_codec.h" -#include "MIH_C_Link_Messages.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -void eRALlte_action_request(MIH_C_Message_Link_Action_request_t* messageP); - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_constants.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_constants.h deleted file mode 100644 index 5939378a7f..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_constants.h +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#ifndef __RAL_LTE_CONS_H__ -#define __RAL_LTE_CONS_H__ - -#include <sys/types.h> - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -//----------------------------------------------------------------------------- -#define DEFAULT_LOCAL_PORT_RAL "1235" -#define DEFAULT_REMOTE_PORT_MIHF "1025" -#define DEFAULT_IP_ADDRESS_MIHF "127.0.0.1" -#define DEFAULT_IP_ADDRESS_RAL "127.0.0.1" -#define DEFAULT_LINK_ID "link" -#define DEFAULT_MIHF_ID "mihf1" -#define DEFAULT_ADDRESS_3GPP "0335060080149150" - -#define DEFAULT_PLMN "208020" -#define DEFAULT_MCC "208" // France -#define DEFAULT_MNC "020" // Bouygues Telecom - -//----------------------------------------------------------------------------- -#define MIH_C_RADIO_POLLING_INTERVAL_MICRO_SECONDS 50000 -#define MIH_C_RADIO_POLLING_INTERVAL_SECONDS 0 - -//----------------------------------------------------------------------------- -// Constants for scenario -#define PREDEFINED_MIH_NETWORK_ID "eurecom" -#define PREDEFINED_MIH_NETAUX_ID "netaux" - -#define PREDEFINED_CHANNEL_ID 2 -#define PREDEFINED_CLASSES_SERVICE_SUPPORTED 2 -#define PREDEFINED_QUEUES_SUPPORTED 2 - -#define PREDEFINED_LINK_DETECTED_INDICATION_SIG_STRENGTH 5 -#define PREDEFINED_LINK_DETECTED_INDICATION_SINR 45 -#define PREDEFINED_LINK_DETECTED_INDICATION_LINK_DATA_RATE 1000 - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_mih_msg.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_mih_msg.h deleted file mode 100644 index 4ad63a80f8..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_mih_msg.h +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file eRALlte_mih_msg.h - * \brief - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __RAL_LTE_MIH_MSG_H__ -#define __RAL_LTE_MIH_MSG_H__ - -#include <sys/types.h> - -#include "MIH_C_Types.h" -#include "MIH_C_header_codec.h" -#include "MIH_C_Link_Primitives.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -char* g_mihf_ip_address; -char* g_mihf_remote_port; -int g_sockd_mihf; - -char* g_ral_ip_address; -char* g_ral_listening_port_for_mihf; - -char* g_link_id; -char* g_mihf_id; - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -int eRALlte_mihf_connect(void); - -int eRALlte_mih_link_process_message(void); - -/* - * -------------------------------------------------------------------------- - * MIH service management messages - * -------------------------------------------------------------------------- - */ - -/* MIH_C_MESSAGE_LINK_REGISTER_INDICATION_ID */ -void eRALlte_send_link_register_indication( - MIH_C_TRANSACTION_ID_T *transaction_idP); - -/* MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_CONFIRM_ID */ -void eRALlte_send_capability_discover_confirm( - MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *link_evt_listP, - MIH_C_LINK_CMD_LIST_T *link_cmd_listP); - -/* MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_CONFIRM_ID */ -void eRALlte_send_event_subscribe_confirm( - MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *link_event_listP); - -/* MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_CONFIRM_ID */ -void eRALlte_send_event_unsubscribe_confirm( - MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *link_event_listP); - -/* - * -------------------------------------------------------------------------- - * MIH event messages - * -------------------------------------------------------------------------- - */ - -/* MIH_C_MESSAGE_LINK_DETECTED_INDICATION_ID */ -void eRALlte_send_link_detected_indication( - MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_DET_INFO_T *link_detected_infoP); - -/* MIH_C_MESSAGE_LINK_UP_INDICATION_ID */ -void eRALlte_send_link_up_indication( - MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_LINK_ADDR_T *old_access_routerP, - MIH_C_LINK_ADDR_T *new_access_routerP, - MIH_C_IP_RENEWAL_FLAG_T *ip_renewal_flagP, - MIH_C_IP_MOB_MGMT_T *mobility_mngtP); - -/* MIH_C_MESSAGE_LINK_DOWN_INDICATION_ID */ -void eRALlte_send_link_down_indication( - MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_LINK_ADDR_T *old_access_routerP, - MIH_C_LINK_DN_REASON_T *reason_codeP); - -/* MIH_C_MESSAGE_LINK_PARAMETERS_REPORT_INDICATION_ID */ -void eRALlte_send_link_parameters_report_indication( - MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_LINK_PARAM_RPT_LIST_T *link_parameters_report_listP); - -/* MIH_C_MESSAGE_LINK_GOING_DOWN_INDICATION_ID */ -void eRALlte_send_link_going_down_indication( - MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_UNSIGNED_INT2_T *time_intervalP, - MIH_C_LINK_GD_REASON_T *link_going_down_reasonP); - -/* MIH_C_MESSAGE_LINK_HANDOVER_IMMINENT_INDICATION_ID */ - -/* MIH_C_MESSAGE_LINK_HANDOVER_COMPLETE_INDICATION_ID */ - -/* MIH_C_MESSAGE_LINK_PDU_TRANSMIT_STATUS_INDICATION_ID */ - -/* - * -------------------------------------------------------------------------- - * MIH command messages - * -------------------------------------------------------------------------- - */ - -/* MIH_C_MESSAGE_LINK_GET_PARAMETERS_CONFIRM_ID */ -void eRALlte_send_get_parameters_confirm( - MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_PARAM_LIST_T *link_parameters_status_listP, - MIH_C_LINK_STATES_RSP_LIST_T *link_states_response_listP, - MIH_C_LINK_DESC_RSP_LIST_T *link_descriptors_response_listP); - -/* MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_CONFIRM_ID */ -void eRALlte_send_configure_thresholds_confirm( - MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_CFG_STATUS_LIST_T *link_configure_status_listP); - -/* MIH_C_MESSAGE_LINK_ACTION_CONFIRM_ID */ -void eRALlte_send_link_action_confirm( - MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_SCAN_RSP_LIST_T *scan_response_setP, - MIH_C_LINK_AC_RESULT_T *link_action_resultP); - -/* - * -------------------------------------------------------------------------- - * MIH information messages - * -------------------------------------------------------------------------- - */ - -/****************************************************************************/ - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_parameters.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_parameters.h deleted file mode 100644 index 73f0054c33..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_parameters.h +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file eRALlte_parameters.h - * \brief - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __RAL_LTE_PARAMETERS_H__ -#define __RAL_LTE_PARAMETERS_H__ - -#include "MIH_C.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -void eRALlte_get_parameters_request(MIH_C_Message_Link_Get_Parameters_request_t* messageP); - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_proto.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_proto.h deleted file mode 100644 index 940ed460d2..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_proto.h +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file eRALlte_proto.h - * \brief - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __RAL_LTE_PROTO_H__ -#define __RAL_LTE_PROTO_H__ - -#include "eRALlte_variables.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/* - * Functions defined in eRALlte_NAS.c - */ - -void eRALlte_NAS_get_MTs_list(void); -int eRALlte_NAS_update_MTs_list(void); - -int eRALlte_NAS_process_message(void); -int eRALlte_NAS_send_rb_establish_request(int mt_ix, int ch_ix); -int eRALlte_NAS_send_rb_release_request(int mt_ix, int ch_ix); - -#ifdef RAL_REALTIME -int TQAL_process_NAS_message(int ioctl_obj, int ioctl_cmd, - int mt_ix, int ch_ix); -#endif - -/* - * Functions defined in eRALlte_process.c - */ -int eRALlte_process_find_channel(unsigned int cnxid, int* mt_ix, int* ch_ix); -int eRALlte_process_find_new_channel(int mt_ix); -void eRALlte_process_clean_channel(struct ral_lte_channel* pchannel); -void eRALlte_process_verify_pending_mt_status(void); -char* eRALlte_process_mt_addr_to_string(const unsigned char* mt_addr); -void eRALlte_process_mt_addr_to_l2id(const unsigned char* mt_addr, unsigned int* l2id); -int eRALlte_process_cmp_mt_addr(const char* mt_addr, const char* l2id); -int eRALlte_process_find_mt_by_addr(const char* mt_addr); -int eRALlte_process_map_qos(int mt_ix, int ch_ix); - -#endif - diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_subscribe.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_subscribe.h deleted file mode 100644 index 4f649998ae..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_subscribe.h +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file eRALlte_subscribe.h - * \brief - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __RAL_LTE_SUBSCRIBE_H__ -#define __RAL_LTE_SUBSCRIBE_H__ - -#include "MIH_C.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -void eRALlte_subscribe_request(MIH_C_Message_Link_Event_Subscribe_request_t* msgP); - -void eRALlte_unsubscribe_request(MIH_C_Message_Link_Event_Unsubscribe_request_t* msgP); - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_thresholds.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_thresholds.h deleted file mode 100644 index fbd0a4039c..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_thresholds.h +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file eRALlte_thresholds.h - * \brief - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __RAL_LTE_THRESHOLDS_H__ -#define __RAL_LTE_THRESHOLDS_H__ - -#include "MIH_C.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -//LIST(MIH_C_LINK_CFG_PARAM, g_link_cfg_param_thresholds); - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -void eRALlte_configure_thresholds_request(MIH_C_Message_Link_Configure_Thresholds_request_t* messageP); - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_variables.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_variables.h deleted file mode 100644 index 48d4d1f645..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/eRALlte_variables.h +++ /dev/null @@ -1,239 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#ifndef __RAL_LTE_VAR_H__ -#define __RAL_LTE_VAR_H__ - -#include "rrc_d_types.h" -#include "nas_rg_netlink.h" - -#include "MIH_C_Types.h" -#include "MIH_C_header_codec.h" -#include "MIH_C_Link_Primitives.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -#define RAL_DUMMY -//#define RAL_REALTIME - - -/* Radio Bearer attachment status; must be the same as NAS interface */ -#define RB_CONNECTED NAS_CONNECTED -#define RB_DISCONNECTED NAS_DISCONNECTED - -#ifdef RAL_REALTIME -/* - * -------------------------------------------------------------------------- - * Arguments ioctl command - * -------------------------------------------------------------------------- - */ - -//arg[0] -#define IO_OBJ_STATS 0 -#define IO_OBJ_CNX 1 -#define IO_OBJ_RB 2 -#define IO_OBJ_MC 3 // multicast -//arg[1] -#define IO_CMD_ADD 0 -#define IO_CMD_DEL 1 -#define IO_CMD_LIST 2 - -#endif // RAL_REALTIME - -/* - * -------------------------------------------------------------------------- - * Access Router configuration - * -------------------------------------------------------------------------- - */ - -/* Maximum number of supported Radio Bearers */ -#define RAL_MAX_RB NAS_RG_NETL_MAX_RABS - -/* Maximum number of supported Mobile Terminals */ -#define RAL_MAX_MT NAS_RG_NETL_MAX_MTs - -/* Maximum number of Radio Bearers per User Equipment */ -#define RAL_MAX_RB_PER_UE 32 - -/* Default Radio Bearer identifier */ -#define RAL_DEFAULT_RAB_ID 6 // RBID 5 => MBMS, 6 => DEFAULTRAB, 7+ => others - -/* Default Radio Bearer QoS value */ -#define RAL_DEFAULT_RAB_QoS 2 // RRC_QOS_CONV_64_64 - -/* Default current cell identifier */ -#define RAL_DEFAULT_CELL_ID 5 - -/* Default bit rates */ -#define RAL_BITRATE_32k 32000 -#define RAL_BITRATE_64k 64000 -#define RAL_BITRATE_128k 128000 -#define RAL_BITRATE_256k 256000 -#define RAL_BITRATE_320k 320000 -#define RAL_BITRATE_384k 384000 -#define RAL_BITRATE_440k 440000 - -/* Public Lan Mobile Network */ -#define DEFAULT_PLMN_SIZE 3 -#ifdef DEFINE_GLOBAL_CONSTANTS -const u_int8_t DefaultPLMN[DEFAULT_PLMN_SIZE] = {0x20, 0x80, 0x20}; -#else -extern const u_int8_t DefaultPLMN[DEFAULT_PLMN_SIZE]; -#endif - -/* - * Destination addresses - * --------------------- - */ -enum { - ADDR_MT1 = 0, - ADDR_MT2, - ADDR_MBMS, - ADDR_MT3, - ADDR_MAX -}; - -#ifdef DEFINE_GLOBAL_CONSTANTS // Modified MW 23/05/13 -const char DestIpv6Addr[ADDR_MAX][16] = { // DUMMY - // MT1 - 2001:660:382:14:335:600:8014:9150 - {0x20,0x01,0x06,0x60,0x03,0x82,0x00,0x14,0x03,0x35,0x06,0x00,0x80,0x14,0x91,0x50}, - // MT2 - 2001:660:382:14:335:600:8014:9151 - {0x20,0x01,0x06,0x60,0x03,0x82,0x00,0x14,0x03,0x35,0x06,0x00,0x80,0x14,0x91,0x51}, - // Multicast - FF3E:20:2001:DB8::43 - {0xFF,0x3E,0x00,0x20,0x20,0x01,0x0D,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43}, - // MT3 - 2001:660:382:14:335:600:8014:9153 - {0x20,0x01,0x06,0x60,0x03,0x82,0x00,0x14,0x03,0x35,0x06,0x00,0x80,0x14,0x91,0x53} -}; -#else -extern const char DestIpv6Addr[ADDR_MAX][16]; -#endif - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/* List of link action types */ -TYPEDEF_BITMAP8(MIH_C_LINK_AC_TYPE_LIST) - -/* - * Radio Bearer data - */ -struct ral_lte_channel { - uint32_t cnx_id; - uint8_t multicast; - // MIHF parameters ix=0 UPLINK, ix=1 DOWNLINK - uint16_t flowId[2]; - uint16_t classId[2]; - float resBitrate[2]; - float meanBitrate[2]; - float bktDepth[2]; - float pkBitrate[2]; - float MTU[2]; - //NAS driver parameters - uint16_t rbId; - uint16_t RadioQoSclass; - uint16_t dscpUL; - uint16_t dscpDL; - uint16_t nas_state; - uint16_t status; -}; - -/* - * Mobile Terminal data - */ -struct ral_lte_mt { - /* The identifier of the link that is associated with a PoA */ - MIH_C_LINK_TUPLE_ID_T ltid; - uint8_t ipv6_addr[16]; - uint32_t ipv6_l2id[2]; - uint32_t ue_id; - struct ral_lte_channel radio_channel[RAL_MAX_RB]; - int num_rbs; - int num_class; - int nas_state; - int mt_state; -}; - -/* - * Multicast data - */ -struct ral_lte_mcast { - /* The identifier of the multicast link that is associated with a PoA */ - MIH_C_LINK_TUPLE_ID_T ltid; - struct ral_lte_channel radio_channel; - uint8_t mc_group_addr[16]; -}; - -/* - * RAL LTE internal data - */ -struct ral_lte_priv { - - uint8_t plmn[3]; - int curr_cellId; - int num_connected_mts; - - uint8_t pending_req_flag; - uint8_t pending_req_mt_ix; - uint8_t pending_req_ch_ix; - MIH_C_FLOW_ID_T pending_req_fid; - - struct ral_lte_mt pending_mt; - int pending_mt_timer; - - struct ral_lte_mt mt[RAL_MAX_MT]; - struct ral_lte_mcast mcast; - - /* MIH-INTERFACE data */ - MIH_C_LINK_AC_TYPE_LIST_T mih_supported_link_action_list; - MIH_C_LINK_EVENT_LIST_T mih_supported_link_event_list; - MIH_C_LINK_CMD_LIST_T mih_supported_link_command_list; - - MIH_C_LINK_EVENT_LIST_T mih_subscribe_req_event_list; - - MIH_C_LINK_AC_TYPE_T pending_req_action; - MIH_C_STATUS_T pending_req_status; - MIH_C_LINK_AC_RESULT_T pending_req_ac_result; - MIH_C_TRANSACTION_ID_T pending_req_transaction_id; -}; - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -extern struct ral_lte_priv *ralpriv; - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -#endif - diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_action.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_action.h deleted file mode 100755 index 0879be98fa..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_action.h +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file mRALlte_action.h - * \brief - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MRALLTE_ACTION_H__ -# define __MRALLTE_ACTION_H__ -//----------------------------------------------------------------------------- -# ifdef MRALLTE_ACTION_C -# define private_mRALlte_action(x) x -# define protected_mRALlte_action(x) x -# define public_mRALlte_action(x) x -# else -# ifdef MRAL_MODULE -# define private_mRALlte_action(x) -# define protected_mRALlte_action(x) extern x -# define public_mRALlte_action(x) extern x -# else -# define private_mRALlte_action(x) -# define protected_mRALlte_action(x) -# define public_mRALlte_action(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -#include "mRALlte_constants.h" -#include "mRALlte_mih_msg.h" -//----------------------------------------------------------------------------- -protected_mRALlte_action(MIH_C_LINK_ACTION_T g_link_action;) -//----------------------------------------------------------------------------- -protected_mRALlte_action(void mRALlte_action_request(MIH_C_Message_Link_Action_request_t* messageP);) - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_constants.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_constants.h deleted file mode 100755 index 6899c9f835..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_constants.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef __MRALLTE_CONSTANTS_H__ -#define __MRALLTE_CONSTANTS_H__ -//----------------------------------------------------------------------------- -#define DEFAULT_LOCAL_PORT_RAL "1235" -#define DEFAULT_REMOTE_PORT_MIHF "1025" -#define DEFAULT_IP_ADDRESS_MIHF "127.0.0.1" -#define DEFAULT_IP_ADDRESS_RAL "127.0.0.1" -#define DEFAULT_LINK_ID "link" //"lte" -#define DEFAULT_MIHF_ID "mihf1" -#define DEFAULT_ADDRESS_3GPP "0335060080149150" - -//----------------------------------------------------------------------------- -#define MIH_C_RADIO_POLLING_INTERVAL_MICRO_SECONDS 50000 -#define MIH_C_RADIO_POLLING_INTERVAL_SECONDS 0 -//----------------------------------------------------------------------------- -// Constants for scenario -#define PREDEFINED_MIH_NETWORK_ID "eurecom" -#define PREDEFINED_MIH_NETAUX_ID "netaux" - -#define PREDEFINED_CHANNEL_ID 2 -#define PREDEFINED_CLASSES_SERVICE_SUPPORTED 2 -#define PREDEFINED_QUEUES_SUPPORTED 2 - -#define PREDEFINED_LINK_GOING_DOWN_INDICATION_SIG_STRENGTH 20 -#define PREDEFINED_LINK_DETECTED_INDICATION_SIG_STRENGTH 10 -#define PREDEFINED_LINK_DETECTED_INDICATION_SINR 45 -#define PREDEFINED_LINK_DETECTED_INDICATION_LINK_DATA_RATE 1000 - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_get.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_get.h deleted file mode 100755 index 417ba9ebb6..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_get.h +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file mRALlte_get.h - * \brief - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MRALLTE_GET_H__ -# define __MRALLTE_GET_H__ -//----------------------------------------------------------------------------- -# ifdef MRALLTE_GET_C -# define private_mRALlte_get(x) x -# define protected_mRALlte_get(x) x -# define public_mRALlte_get(x) x -# else -# ifdef MRAL_MODULE -# define private_mRALlte_get(x) -# define protected_mRALlte_get(x) extern x -# define public_mRALlte_get(x) extern x -# else -# define private_mRALlte_get(x) -# define protected_mRALlte_get(x) -# define public_mRALlte_get(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -public_mRALlte_get(void MIH_C_3GPP_ADDR_load_3gpp_str_address(MIH_C_3GPP_ADDR_T* _3gpp_addrP, u_int8_t* strP);) - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_main.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_main.h deleted file mode 100755 index 59dfdfcb8a..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_main.h +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file mRALlte_main.h - * \brief This file defines the prototypes of the functions for starting the module mRALlteInt. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MRALLTE_MAIN_H__ -# define __MRALLTE_MAIN_H__ -//----------------------------------------------------------------------------- -# ifdef MRALLTE_MAIN_C -# define private_mRALlte_main(x) x -# define protected_mRALlte_main(x) x -# define public_mRALlte_main(x) x -# else -# ifdef MRAL_MODULE -# define private_mRALlte_main(x) -# define protected_mRALlte_main(x) extern x -# define public_mRALlte_main(x) extern x -# else -# define private_mRALlte_main(x) -# define protected_mRALlte_main(x) -# define public_mRALlte_main(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <netdb.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/time.h> -#include <ctype.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <getopt.h> -#include <libgen.h> -//----------------------------------------------------------------------------- -#endif - - - - - - diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_mih_msg.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_mih_msg.h deleted file mode 100755 index 19a32b8b98..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_mih_msg.h +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file mRALlte_mih_msg.h - * \brief This file defines the prototypes of the functions for coding and decoding of MIH Link messages. - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MRALLTE_MIH_MSG_H__ -# define __MRALLTE_MIH_MSG_H__ -//----------------------------------------------------------------------------- -# ifdef MRALLTE_MIH_MSG_C -# define private_mRALlte_mih_msg(x) x -# define protected_mRALlte_mih_msg(x) x -# define public_mRALlte_mih_msg(x) x -# else -# ifdef MRAL_MODULE -# define private_mRALlte_mih_msg(x) -# define protected_mRALlte_mih_msg(x) extern x -# define public_mRALlte_mih_msg(x) extern x -# else -# define private_mRALlte_mih_msg(x) -# define protected_mRALlte_mih_msg(x) -# define public_mRALlte_mih_msg(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <netdb.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/time.h> -#include <ctype.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <getopt.h> -#include <libgen.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -#include "mRALlte_constants.h" -#include "mRALlte_get.h" -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -#define MSG_CODEC_RECV_BUFFER_SIZE 16400 -#define MSG_CODEC_SEND_BUFFER_SIZE 16400 -//----------------------------------------------------------------------------- -protected_mRALlte_mih_msg(char* g_mihf_remote_port;) -protected_mRALlte_mih_msg(char* g_mihf_ip_address;) -protected_mRALlte_mih_msg(char* g_ral_ip_address;) -protected_mRALlte_mih_msg(char* g_ral_listening_port_for_mihf;) -protected_mRALlte_mih_msg(char* g_link_id;) -protected_mRALlte_mih_msg(char* g_mihf_id;) -protected_mRALlte_mih_msg(int g_sockd_mihf;) -protected_mRALlte_mih_msg(char g_msg_print_buffer[8192];) - -//----------------------------------------------------------------------------- -protected_mRALlte_mih_msg(u_int8_t g_msg_codec_recv_buffer[MSG_CODEC_RECV_BUFFER_SIZE];) -protected_mRALlte_mih_msg(u_int8_t g_msg_codec_send_buffer[MSG_CODEC_SEND_BUFFER_SIZE];) -//----------------------------------------------------------------------------- -public_mRALlte_mih_msg( int mRALlte_send_to_mih(u_int8_t *bufferP, size_t lenP);) - -protected_mRALlte_mih_msg( void mRALlte_print_buffer (char * bufferP, int lengthP);) -protected_mRALlte_mih_msg( int mRALlte_mihf_connect (void);) -protected_mRALlte_mih_msg( void mRALlte_send_link_register_indication (MIH_C_TRANSACTION_ID_T *transaction_idP);) -protected_mRALlte_mih_msg( void mRALlte_send_link_detected_indication (MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_DET_INFO_T *link_detected_infoP);) - -protected_mRALlte_mih_msg( void mRALlte_send_link_up_indication(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_LINK_ADDR_T *old_access_routerP, - MIH_C_LINK_ADDR_T *new_access_routerP, - MIH_C_IP_RENEWAL_FLAG_T *ip_renewal_flagP, - MIH_C_IP_MOB_MGMT_T *mobility_management_supportP);) - -protected_mRALlte_mih_msg( void mRALlte_send_link_parameters_report_indication(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_LINK_PARAM_RPT_LIST_T *link_parameters_report_listP);) - -protected_mRALlte_mih_msg( void mRALlte_send_link_going_down_indication(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_UNSIGNED_INT2_T *time_intervalP, - MIH_C_LINK_GD_REASON_T *link_going_down_reasonP);) - -protected_mRALlte_mih_msg( void mRALlte_send_link_down_indication(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_LINK_ADDR_T *old_access_routerP, - MIH_C_LINK_DN_REASON_T *reason_codeP);) - -protected_mRALlte_mih_msg( void mRALlte_send_link_action_confirm(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_SCAN_RSP_LIST_T *scan_response_setP, - MIH_C_LINK_AC_RESULT_T *link_action_resultP);) - -protected_mRALlte_mih_msg( void mRALte_send_capability_discover_confirm(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *supported_link_event_listP, - MIH_C_LINK_CMD_LIST_T *supported_link_command_listP);) - -protected_mRALlte_mih_msg( void mRALte_send_event_subscribe_confirm (MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *response_link_event_listP);) - -protected_mRALlte_mih_msg( void mRALte_send_event_unsubscribe_confirm (MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *response_link_event_listP);) - -protected_mRALlte_mih_msg( void mRALte_send_configure_thresholds_confirm(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_CFG_STATUS_LIST_T *link_configure_status_listP);) - -protected_mRALlte_mih_msg( void mRALte_send_get_parameters_confirm (MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_PARAM_LIST_T *link_parameters_status_listP, - MIH_C_LINK_STATES_RSP_LIST_T *link_states_response_listP, - MIH_C_LINK_DESC_RSP_LIST_T *link_descriptors_response_listP);) - -private_mRALlte_mih_msg( int mRALlte_mih_link_msg_decode (Bit_Buffer_t* bbP, MIH_C_Message_Wrapper_t *message_wrapperP);) -protected_mRALlte_mih_msg( int mRALlte_mih_link_process_message (void);) -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_parameters.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_parameters.h deleted file mode 100755 index fa55f4bfde..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_parameters.h +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file mRALlte_parameters.h - * \brief - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MRALLTE_PARAMETERS_H__ -# define __MRALLTE_PARAMETERS_H__ -//----------------------------------------------------------------------------- -# ifdef MRALLTE_PARAMETERS_C -# define private_mRALlte_parameters(x) x -# define protected_mRALlte_parameters(x) x -# define public_mRALlte_parameters(x) x -# else -# ifdef MRAL_MODULE -# define private_mRALlte_parameters(x) -# define protected_mRALlte_parameters(x) extern x -# define public_mRALlte_parameters(x) extern x -# else -# define private_mRALlte_parameters(x) -# define protected_mRALlte_parameters(x) -# define public_mRALlte_parameters(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -#include "mRALlte_constants.h" -#include "mRALlte_mih_msg.h" -//----------------------------------------------------------------------------- -protected_mRALlte_parameters(void mRALlte_get_parameters_request(MIH_C_Message_Link_Get_Parameters_request_t* messageP);) - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_proto.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_proto.h deleted file mode 100755 index 69070c6d87..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_proto.h +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef __RAL_LTE_PROTO_H__ -#define __RAL_LTE_PROTO_H__ - - - - -//mRALuD_NAS.c -int IAL_decode_NAS_message(void); -int IAL_process_DNAS_message(int ioctl_obj, int ioctl_cmd, int ioctl_cellid); - -//mRALuD_process.c -void IAL_NAS_measures_init(void); -void IAL_NAS_measures_update(int i); -void IAL_integrate_measure(int measure, int i); -void rallte_NAS_measures_polling(void); -int rallte_NAS_corresponding_cell(int req_index); -void rallte_verifyPendingConnection(void); - -#endif - diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_subscribe.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_subscribe.h deleted file mode 100755 index 82a60468de..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_subscribe.h +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file mRALlte_subscribe.h - * \brief - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MRALLTE_SUBSCRIBE_H__ -# define __MRALLTE_SUBSCRIBE_H__ -//----------------------------------------------------------------------------- -# ifdef MRALLTE_SUBSCRIBE_C -# define private_mRALlte_subscribe(x) x -# define protected_mRALlte_subscribe(x) x -# define public_mRALlte_subscribe(x) x -# else -# ifdef MRAL_MODULE -# define private_mRALlte_subscribe(x) -# define protected_mRALlte_subscribe(x) extern x -# define public_mRALlte_subscribe(x) extern x -# else -# define private_mRALlte_subscribe(x) -# define protected_mRALlte_subscribe(x) -# define public_mRALlte_subscribe(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- -#include "mRALlte_constants.h" -#include "mRALlte_mih_msg.h" -//----------------------------------------------------------------------------- -protected_mRALlte_subscribe(void mRALlte_subscribe_request (MIH_C_Message_Link_Event_Subscribe_request_t* messageP);) -protected_mRALlte_subscribe(void mRALlte_unsubscribe_request(MIH_C_Message_Link_Event_Unsubscribe_request_t* messageP);) - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_thresholds.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_thresholds.h deleted file mode 100755 index 7c85054245..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_thresholds.h +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -/*! \file mRALlte_thresholds.h - * \brief - * \author BRIZZOLA Davide, GAUTHIER Lionel, MAUREL Frederic, WETTERWALD Michelle - * \date 2012 - * \version - * \note - * \bug - * \warning - */ - -#ifndef __MRALLTE_THRESHOLDS_H__ -# define __MRALLTE_THRESHOLDS_H__ -//----------------------------------------------------------------------------- -# ifdef MRALLTE_THRESHOLDS_C -# define private_mRALlte_thresholds(x) x -# define protected_mRALlte_thresholds(x) x -# define public_mRALlte_thresholds(x) x -# else -# ifdef MRAL_MODULE -# define private_mRALlte_thresholds(x) -# define protected_mRALlte_thresholds(x) extern x -# define public_mRALlte_thresholds(x) extern x -# else -# define private_mRALlte_thresholds(x) -# define protected_mRALlte_thresholds(x) -# define public_mRALlte_thresholds(x) extern x -# endif -# endif -//----------------------------------------------------------------------------- -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <ctype.h> -//----------------------------------------------------------------------------- -#include "MIH_C.h" -#include "mRALlte_mih_msg.h" -//----------------------------------------------------------------------------- -protected_mRALlte_thresholds(LIST(MIH_C_LINK_CFG_PARAM, g_link_cfg_param_thresholds);) -//----------------------------------------------------------------------------- -protected_mRALlte_thresholds(void mRALlte_configure_thresholds_request(MIH_C_Message_Link_Configure_Thresholds_request_t* messageP);) -public_mRALlte_thresholds( void mRALlte_check_thresholds_signal_strength(MIH_C_THRESHOLD_VAL_T new_valP, MIH_C_THRESHOLD_VAL_T old_valP);) - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_variables.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_variables.h deleted file mode 100755 index af947d258d..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/mRALlte_variables.h +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#ifndef __RAL_LTE_VAR_H__ -#define __RAL_LTE_VAR_H__ -//------------------------------------------------------------------- - -#include "rrc_d_types.h" -#include "commonDS.h" -#include "mRALlte_constants.h" -#include "MIH_C.h" - -/*************************************************************************** - CONSTANTS - ***************************************************************************/ -#define RAL_DUMMY -//#define RAL_REALTIME -//#define MRALU_SIMU_LINKDOWN -//#define DEBUG_MRALU_MEASURES -//#define UPDATE - - -#define RALU_MT_EVENT_MAP MIH_EVENT_Link_AdvertisementIndication + MIH_EVENT_Link_Parameters_ReportIndication + MIH_EVENT_Link_UpIndication + MIH_EVENT_Link_DownIndication - -#define MIHLink_MAX_LENGTH 500 -#define MAX_NUMBER_BS 3 /* Max number of base stations */ -#define CONF_UNKNOWN_CELL_ID 0 -#define UMTS_INTF_NAME "graal0" - -//Attachment status -#define UNKNOWN 9 -#define CONNECTED 1 -#define DISCONNECTED 0 -//max number RB supported (27 in Spec) -#define RAL_MAX_RB 5 - -// constant for integrating measures according to the formula -// y[n] = (1-LAMBDA)*u[n-1] + LAMBDA*u[n] -#define LAMBDA 8 -#define MEAS_MAX_RSSI 110 - -/*************************************************************************** - VARIABLES - ***************************************************************************/ -struct ral_lte_priv { - // only to call ralu_verifyPendingConnection - uint8_t pending_req_flag; - // network parameters - uint16_t cell_id; - uint16_t nas_state; - int state; - uint32_t curr_signal_level; - uint32_t ipv6_l2id[2]; - //measures - uint8_t req_num_bs; - uint16_t req_cell_id[MAX_NUMBER_BS]; - uint32_t req_prov_id[MAX_NUMBER_BS]; - uint16_t req_order_index[MAX_NUMBER_BS]; - int num_measures; - uint16_t meas_cell_id[MAX_NUMBER_BS]; - uint32_t last_meas_level[MAX_NUMBER_BS]; - uint32_t integrated_meas_level[MAX_NUMBER_BS]; - uint32_t prev_integrated_meas_level[MAX_NUMBER_BS]; - uint32_t provider_id[MAX_NUMBER_BS]; - //Radio Bearers - uint16_t num_rb; - uint16_t rbId[RAL_MAX_RB]; - uint16_t QoSclass[RAL_MAX_RB]; - uint16_t dscp[RAL_MAX_RB]; - // statistics - uint32_t rx_packets; - uint32_t tx_packets; - uint32_t rx_bytes; - uint32_t tx_bytes; - uint32_t rx_errors; - uint32_t tx_errors; - uint32_t rx_dropped; - uint32_t tx_dropped; - char buffer[800]; // For ioctl with NAS driver - - // MIH-INTERFACE data - // Initialised, then read-only, supported actions - MIH_C_LINK_AC_TYPE_T mih_supported_action_list; - // action currently processed - MIH_C_LINK_AC_TYPE_T pending_req_action; - // actions requested by MIH-H - MIH_C_LINK_AC_TYPE_T req_action_list; - - MIH_C_STATUS_T pending_req_status; - MIH_C_LINK_AC_RESULT_T pending_req_ac_result; - MIH_C_TRANSACTION_ID_T pending_req_transaction_id; - // set unset bits by MIH_C_Message_Link_Event_Subscribe_request MIH_C_Message_Link_Event_Unsubscribe_request - MIH_C_LINK_EVENT_LIST_T mih_subscribe_req_event_list; - // Initialised, then read-only - MIH_C_LINK_EVENT_LIST_T mih_supported_link_event_list; - // Initialised, then read-only - MIH_C_LINK_CMD_LIST_T mih_supported_link_command_list; - LIST(MIH_C_LINK_CFG_PARAM, mih_link_cfg_param_thresholds); - // to tell what are the configured thresholds in mih_link_cfg_param_thresholds_list - MIH_C_BOOLEAN_T active_mih_link_cfg_param_threshold[MIH_C_LINK_CFG_PARAM_LIST_LENGTH]; - MIH_C_BOOLEAN_T link_to_be_detected; -}; - -//----------------------------------------------------------------------------- -extern struct ral_lte_priv *ralpriv; - -#endif - diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nasUE_config.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nasUE_config.h deleted file mode 100755 index b4a2db57cf..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nasUE_config.h +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef __NASUE_CONFIG_H__ -#define __NASUE_CONFIG_H__ - -#ifdef MIH_USER_CONTROL -#define MIH_USER_IP_ADDRESS "127.0.0.1" -#define MIH_USER_REMOTE_PORT "0" -#define NAS_IP_ADDRESS "127.0.0.1" -#define NAS_LISTENING_PORT_FOR_MIH_USER "22222" -#define RSSI_INCREMENT_STEP 5 -#endif -//#define SOCKET_RAL_TD_CDMA_NAME "/tmp/graal" - -#define MIHLink_MAX_LENGTH 500 - - -//max number of UE per BS -// Warning : This must be coordinated with the number of FIFOs in the RG (rrc_sap.h) - -// max number of cells or RGs -// to be coordinated with NAS list of RGs -#define maxCells 2 - - -//// Daidalos II -//// parameters are defined in tables, -//// - -#define CONF_ACTIVATE_REQ 2 -#define CONF_DEACTIVATE_REQ 3 -#define CONF_ALL_MEAS_REQ 4 -#define CONF_SEL_MEAS_REQ 5 - -#define CONF_NUM_MEAS 5 -#define CONF_PERIOD_MEAS 30 // 30*100 = 3000 ms = 3 secs -// MIHF measure every CONF_PERIOD_MEAS * 100 ms -// Ex : CONF_PERIOD_MEAS = 20 ==> measure every 2 secs -#define CONF_TEST_DURATION 300 // 60*100 = 60000 ms = 60 secs -// Actual duration = CONF_TEST_DURATION * 100 ms -// must be a mulptiple of CONF_PERIOD_MEAS -#define CONF_TEST_COUNTER CONF_TEST_DURATION/CONF_PERIOD_MEAS - -#define CONF_CURR_CELL_ID 5 - -// start NAS config -#ifdef CONF_NASUE_DUMMY - -#define CONF_MT0 0 -#define CONF_MT1 1 - -#define CONF_iid4 2 -int conf_iid6_0[2] = { 406787, 406787}; -int conf_iid6_1[2] = {1351685248, 1368462464}; - - -#define CONF_rx_packets 1529 -#define CONF_tx_packets 254 -#define CONF_rx_bytes 157896 -#define CONF_tx_bytes 32546 -#define CONF_rx_errors 12 -#define CONF_tx_errors 5 -#define CONF_rx_dropped 0 -#define CONF_tx_dropped 24 - -//rb_list -#define CONF_num_rb 2 -int conf_rbId[CONF_num_rb] = {12 ,14 }; -int conf_qoSclass[CONF_num_rb] = {2 ,9 }; -int conf_dscp[CONF_num_rb] = {5 ,25 }; - -// measures -#define CONF_num_cells 3 -int conf_cell_id[CONF_num_cells] = {CONF_CURR_CELL_ID, 8, 2 }; -// LGint conf_level [CONF_num_cells] = {50, 5, 20}; -int conf_level [CONF_num_cells] = {5, 50, 20}; -int conf_provider_id [CONF_num_cells] = {25, 1 , 25 }; - -//float conf_MTU[3] = {1000.,1100.,1200.}; -#endif - -#endif - diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_rg_netlink.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_rg_netlink.h deleted file mode 100755 index c740ef2b5c..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_rg_netlink.h +++ /dev/null @@ -1,242 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef NAS_RG_NTL_H -#define NAS_RG_NTL_H - -#include <net/if.h> -#include <netinet/in.h> - -#include "rrc_d_types.h" - -#define SOCK_TQAL_NAS_PATH "/tmp/SOCK_TQAL_NAS" - - -#define NAS_RG_NETL_MAXLEN 200 -//#define NAS_RG_NETL_MAX_RABS 27 //spec value -#define NAS_RG_NETL_MAX_RABS 5 //test value -#define NAS_RG_NETL_MAX_MEASURE_NB 5 -#define NAS_RG_NETL_MAX_MTs 3 - -#define NAS_CONNECTED 1 //same as NAS interface -#define NAS_DISCONNECTED 0 - -#define NAS_UNICAST 0 -#define NAS_MCAST 2 - -// type of CTL message -#define NAS_RG_MSG_STATISTIC_REQUEST 1 -#define NAS_RG_MSG_STATISTIC_REPLY 2 -#define NAS_RG_MSG_CNX_STATUS_REQUEST 3 -#define NAS_RG_MSG_CNX_STATUS_REPLY 4 -//#define NAS_RG_MSG_CNX_ESTABLISH_REQUEST 5 -//#define NAS_RG_MSG_CNX_ESTABLISH_REPLY 6 -//#define NAS_RG_MSG_CNX_RELEASE_REQUEST 7 -//#define NAS_RG_MSG_CNX_RELEASE_REPLY 8 -#define NAS_RG_MSG_RB_LIST_REQUEST 9 -#define NAS_RG_MSG_RB_LIST_REPLY 10 -#define NAS_RG_MSG_MEASUREMENT_REQUEST 11 -#define NAS_RG_MSG_MEASUREMENT_REPLY 12 -#define NAS_RG_MSG_MEASUREMENT_INDICATION 14 -#define NAS_RG_MSG_CNX_LOSS_INDICATION 15 -#define NAS_RG_MSG_RB_ESTABLISH_REQUEST 16 -#define NAS_RG_MSG_RB_ESTABLISH_REPLY 17 -#define NAS_RG_MSG_RB_RELEASE_REQUEST 18 -#define NAS_RG_MSG_RB_RELEASE_REPLY 19 -#define NAS_RG_MSG_MT_MCAST_JOIN 20 -#define NAS_RG_MSG_MT_MCAST_LEAVE 21 -#define NAS_RG_MSG_MT_MCAST_JOIN_REP 22 -#define NAS_RG_MSG_MT_MCAST_LEAVE_REP 23 - -// Parameter types -//---------------------------------------------------------- -typedef uint16_t netlIPVersion_t; -typedef struct netlIPAddr { - netlIPVersion_t ip_version; - struct in6_addr ip_address; -} netlIPAddr_t; -typedef uint32_t netlStatValue_t; -typedef uint32_t netlProviderId_t; -typedef uint16_t netlCellID_t; // ID of the cell for connection -typedef uint32_t netlMobileId_t; // mobile identifier -typedef uint16_t netlStatus_t; // establishment status -typedef uint32_t netlCnxid_t; -typedef uint16_t netlRadioBearerId_t; -typedef uint16_t netlQoSTrafficClass_t; //QoS traffic class requested -typedef uint16_t netlIPdscp_t; // DSCP code transported to service NAS -typedef struct netlRBDef { - netlRadioBearerId_t rbId; - netlQoSTrafficClass_t QoSclass; - netlIPdscp_t dscp; -} netlrbParms_t; -typedef uint16_t netlNumRBsInList_t; // number of RBs defined in the list -typedef uint16_t netlNumCellsMeas_t; // number of RGs that could be measured -typedef uint32_t netlSigLevel_t; // Signal level measured -typedef struct netlMeasures { - netlCellID_t cell_id; - netlSigLevel_t level; - netlProviderId_t provider_id; -} netlMeasures_t; -typedef uint16_t netlMcast_t; - - - -// Parameter structures -//---------------------------------------------------------- -struct nas_rg_msg_statistic_reply { //FFS - netlStatValue_t rx_packets; - netlStatValue_t tx_packets; - netlStatValue_t rx_bytes; - netlStatValue_t tx_bytes; - netlStatValue_t rx_errors; - netlStatValue_t tx_errors; - netlStatValue_t rx_dropped; - netlStatValue_t tx_dropped; -}; - -struct nas_rg_msg_cnx_status_request { //FFS - netlMobileId_t ue_id; -}; - -struct nas_rg_msg_cnx_status_reply { //FFS - netlMobileId_t ue_id; - uint8_t iid[8]; // interface identification - EUI64 - netlIPAddr_t l3_addr; - netlStatus_t status; - netlNumRBsInList_t num_rb; - netlSigLevel_t signal_level; - netlMobileId_t valid_UEs[NAS_RG_NETL_MAX_MTs]; -}; - -struct nas_rg_msg_rb_list_request { //FFS - netlMobileId_t ue_id; -}; - -struct nas_rg_msg_rb_list_reply { //FFS - netlMobileId_t ue_id; - netlNumRBsInList_t num_rb; // actual number of RBs in the list - netlrbParms_t RBList[NAS_RG_NETL_MAX_RABS]; -}; - -struct nas_rg_msg_signal_loss { - netlMobileId_t ue_id; -}; - -struct nas_rg_msg_rb_establish_request { - netlCnxid_t cnxid; - netlrbParms_t RBParms; - netlIPAddr_t ip_addr; - netlMcast_t mcast_flag; -}; - -struct nas_rg_msg_rb_establish_reply { - netlCnxid_t cnxid; - netlMobileId_t ue_id; - netlrbParms_t RBParms; - netlStatus_t result; -}; -struct nas_rg_msg_rb_release_request { - netlCnxid_t cnxid; - netlMobileId_t ue_id; - netlRadioBearerId_t rbId; -}; - -struct nas_rg_msg_rb_release_reply { - netlCnxid_t cnxid; - netlMobileId_t ue_id; - netlStatus_t result; -}; - -struct nas_rg_msg_mt_mcast_join { - netlCnxid_t cnxid; - netlMobileId_t ue_id; -}; - -struct nas_rg_msg_mt_mcast_leave { - netlCnxid_t cnxid; - netlMobileId_t ue_id; -}; - -struct nas_rg_msg_mt_mcast_join_rep { - netlCnxid_t cnxid; - netlMobileId_t ue_id; - netlStatus_t result; -}; - -struct nas_rg_msg_mt_mcast_leave_rep { - netlCnxid_t cnxid; - netlMobileId_t ue_id; - netlStatus_t result; -}; - -/***** - * TQAL-NAS Primitive - *****/ -struct nas_rg_netl_hdr { - char name[IFNAMSIZ]; - uint16_t type; - uint16_t length; -}; -struct nas_rg_netl_request { - char name[IFNAMSIZ]; - uint16_t type; - uint16_t length; - union { - struct nas_rg_msg_cnx_status_request cnx_stat_req; - struct nas_rg_msg_rb_list_request rb_list_req; - struct nas_rg_msg_rb_establish_request rb_est_req; - struct nas_rg_msg_rb_release_request rb_rel_req; - struct nas_rg_msg_mt_mcast_join mt_mcast_join; - struct nas_rg_msg_mt_mcast_leave mt_mcast_leave; - } tqalNASPrimitive; -}; -struct nas_rg_netl_reply { - char name[IFNAMSIZ]; - uint16_t type; - uint16_t length; - union { - struct nas_rg_msg_statistic_reply statistics_rep; - struct nas_rg_msg_cnx_status_reply cnx_stat_rep; - struct nas_rg_msg_rb_list_reply rb_list_rep; - struct nas_rg_msg_rb_establish_reply rb_est_rep; - struct nas_rg_msg_rb_release_reply rb_rel_rep; - struct nas_rg_msg_mt_mcast_join_rep mt_mc_join_rep; - struct nas_rg_msg_mt_mcast_leave_rep mt_mc_leavce_rep; - } tqalNASPrimitive; -}; -struct nas_rg_netl_indication { - char name[IFNAMSIZ]; - uint16_t type; - uint16_t length; - union { - struct nas_rg_msg_signal_loss sign_loss; - } tqalNASPrimitive; -}; - - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_ue_ioctl.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_ue_ioctl.h deleted file mode 100755 index 5bb1a82238..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_ue_ioctl.h +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef _IAL_IOCTL_H -#define _IAL_IOCTL_H - -#include <sys/ioctl.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <net/if.h> -//LG#include <linux/ipv6.h> -//LG#include <linux/in.h> -//LG#include <linux/in6.h> -//#include <linux/netdevice.h> - -//#include <graal_constant.h> -//#define GRAAL_STATE_IDLE 0 -//#define GRAAL_STATE_CONNECTED 1 -//#define GRAAL_STATE_ESTABLISHMENT_REQUEST 2 -//#define GRAAL_STATE_ESTABLISHMENT_FAILURE 3 -//#define GRAAL_STATE_RELEASE_FAILURE 4 - -//typedef unsigned char uint8_t; -//typedef unsigned short uint16_t; -//typedef unsigned int uint32_t; - -// Temp constants = arguments gioctl -//arg[0] -#define IO_OBJ_STATS 0 -#define IO_OBJ_CNX 1 -#define IO_OBJ_RB 2 -#define IO_OBJ_MEAS 3 -#define IO_OBJ_IMEI 4 -//arg[1] -#define IO_CMD_ADD 0 -#define IO_CMD_DEL 1 -#define IO_CMD_LIST 2 - - - -//LGextern int inet_pton(int af, const char *src, void *dst); -//LGextern char *inet_ntop(int af, const void *src, char *dst, size_t sise); - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_ue_netlink.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_ue_netlink.h deleted file mode 100755 index f068bd46c4..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/nas_ue_netlink.h +++ /dev/null @@ -1,234 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef NAS_UE_NTL_H -#define NAS_UE_NTL_H - -#include <net/if.h> -#include <netinet/in.h> - -#include "rrc_d_types.h" - -//#define SOCK_NAS_PATH "/opt/eurecom/ipc/SOCK_IAL_NAS" -#define SOCK_NAS_PATH "/tmp/SOCK_IAL_NAS" - -// Temp constants = arguments gioctl -//arg[0] -#define IO_OBJ_STATS 0 -#define IO_OBJ_CNX 1 -#define IO_OBJ_RB 2 -#define IO_OBJ_MEAS 3 -#define IO_OBJ_IMEI 4 -//arg[1] -#define IO_CMD_ADD 0 -#define IO_CMD_DEL 1 -#define IO_CMD_LIST 2 - -#define NAS_UE_NETL_MAXLEN 500 -#define NAS_UE_NETL_MAX_RABS 27 -#define NAS_UE_NETL_MAX_MEASURE_NB 5 - -//#define NAS_CONNECTED 1 //same as NAS interface -//#define NAS_DISCONNECTED 0 -#define NAS_CONNECTED 1 //same as NAS interface -#define NAS_DISCONNECTED 0 - -// type of CTL message -#define NAS_UE_MSG_STATISTIC_REQUEST 1 -#define NAS_UE_MSG_STATISTIC_REPLY 2 -#define NAS_UE_MSG_CNX_STATUS_REQUEST 3 -#define NAS_UE_MSG_CNX_STATUS_REPLY 4 -#define NAS_UE_MSG_CNX_ESTABLISH_REQUEST 5 -#define NAS_UE_MSG_CNX_ESTABLISH_REPLY 6 -#define NAS_UE_MSG_CNX_RELEASE_REQUEST 7 -#define NAS_UE_MSG_CNX_RELEASE_REPLY 8 -#define NAS_UE_MSG_CNX_LIST_REQUEST 9 -#define NAS_UE_MSG_CNX_LIST_REPLY 10 -#define NAS_UE_MSG_RB_LIST_REQUEST 15 -#define NAS_UE_MSG_RB_LIST_REPLY 16 -#define NAS_UE_MSG_MEAS_REQUEST 23 -#define NAS_UE_MSG_MEAS_REPLY 24 -#define NAS_UE_MSG_IMEI_REQUEST 25 -#define NAS_UE_MSG_IMEI_REPLY 26 -// -#define NAS_UE_MSG_MEASUREMENT_INDICATION 17 -#define NAS_UE_MSG_CNX_LOSS_INDICATION 18 - - -// Parameter types -//---------------------------------------------------------- -typedef uint16_t netlIPVersion_t; -typedef struct netlIPAddr { - netlIPVersion_t ip_version; - struct in6_addr ip_address; -} netlIPAddr_t; -typedef uint32_t netlStatValue_t; -typedef uint32_t netlProviderId_t; -typedef uint16_t netlCellID_t; // ID of the cell for connection -typedef uint16_t netlConnectionStatus_t; // connection establishment status -typedef uint16_t netlRadioBearerId_t; -typedef uint16_t netlQoSTrafficClass_t; //QoS traffic class requested -typedef uint16_t netlIPdscp_t; // DSCP code transported to service NAS -typedef struct netlRBDef { - netlRadioBearerId_t rbId; - netlQoSTrafficClass_t QoSclass; - netlIPdscp_t dscp; - uint8_t state; -} netlrbParms_t; -typedef uint16_t netlNumRBsInList_t; // number of RBs defined in the list -typedef uint16_t netlNumCellsMeas_t; // number of RGs that could be measured -typedef uint32_t netlSigLevel_t; // Signal level measured -typedef struct netlMeasures { - netlCellID_t cell_id; - netlSigLevel_t level; - netlProviderId_t provider_id; -} netlMeasures_t; - - - -// Parameter structures -//---------------------------------------------------------- -struct nas_ue_msg_statistic_reply { - netlStatValue_t rx_packets; - netlStatValue_t tx_packets; - netlStatValue_t rx_bytes; - netlStatValue_t tx_bytes; - netlStatValue_t rx_errors; - netlStatValue_t tx_errors; - netlStatValue_t rx_dropped; - netlStatValue_t tx_dropped; -}; - -struct nas_ue_msg_cnx_status_reply { - netlCellID_t cellid; // cell identification - uint8_t iid[8]; // interface identification - EUI64 - netlIPAddr_t ip_addr; - netlConnectionStatus_t status; - netlNumRBsInList_t num_rb; - netlSigLevel_t signal_level; -}; - -struct nas_ue_msg_cnx_list_reply { - uint8_t state; - uint16_t cellid; // cell identification - uint32_t iid6[2]; // IPv6 interface identification - uint8_t iid4; // IPv4 interface identification - uint16_t num_rb; - uint16_t nsclassifier; -}; - - -struct nas_ue_msg_cnx_establish_request { - netlCellID_t cellid; // Cell identification -}; - -struct nas_ue_msg_cnx_establish_reply { - netlConnectionStatus_t status; - // uint8_t iid6[8]; // IPv6 interface identification - EUI64 -}; - -struct nas_ue_msg_cnx_release_reply { - netlConnectionStatus_t status; -}; - -struct nas_ue_msg_rb_list_reply { - netlNumRBsInList_t num_rb; // actual number of RBs in the list - netlrbParms_t RBList[NAS_UE_NETL_MAX_RABS]; -}; - -struct nas_ue_msg_measure_request { - netlNumCellsMeas_t num_cells; - netlCellID_t cellid[NAS_UE_NETL_MAX_MEASURE_NB]; // Cell identification - uint16_t num_providers; - netlProviderId_t provider_id[NAS_UE_NETL_MAX_MEASURE_NB]; // Provider identification -}; - -struct nas_ue_msg_measure_reply { - netlNumCellsMeas_t num_cells; - netlMeasures_t measures[NAS_UE_NETL_MAX_MEASURE_NB]; - uint16_t signal_lost_flag; -}; - -struct nas_ue_msg_measure_indicate { - netlMeasures_t measure; -}; - -struct nas_ue_msg_signal_loss { - netlMeasures_t measure; -}; - -struct nas_ue_l2id_reply { - uint32_t l2id [2]; -}; - -/////////////////////////// - -/***** - * IAL-NAS Primitive - *****/ -struct nas_ue_netl_hdr { - char name[IFNAMSIZ]; - uint16_t type; - uint16_t length; -}; -struct nas_ue_netl_request { - char name[IFNAMSIZ]; - uint16_t type; - uint16_t length; - union { - struct nas_ue_msg_cnx_establish_request cnx_req; - struct nas_ue_msg_measure_request meas_req; - } ialNASPrimitive; -}; -struct nas_ue_netl_reply { - char name[IFNAMSIZ]; - uint16_t type; - uint16_t length; - union { - struct nas_ue_msg_statistic_reply statistics_rep; - struct nas_ue_msg_cnx_status_reply cnx_stat_rep; - struct nas_ue_msg_cnx_list_reply cnx_list_rep; - struct nas_ue_msg_cnx_establish_reply cnx_est_rep; - struct nas_ue_msg_cnx_release_reply cnx_rel_rep; - struct nas_ue_msg_rb_list_reply rb_list_rep; - struct nas_ue_msg_measure_reply meas_rep; - struct nas_ue_l2id_reply l2id_rep; - } ialNASPrimitive; -}; -struct nas_ue_netl_indication { - char name[IFNAMSIZ]; - uint16_t type; - uint16_t length; - union { - struct nas_ue_msg_measure_indicate meas_ind; - struct nas_ue_msg_signal_loss sign_loss; - } ialNASPrimitive; -}; - - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/rrc_d_types.h b/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/rrc_d_types.h deleted file mode 100755 index f480701d11..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/INCLUDE/rrc_d_types.h +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#ifndef __RRC_DTYPES_H__ -#define __RRC_DTYPES_H__ - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; - - -#endif diff --git a/openair3/RAL-LTE/RAL-DUMMY/MSCGEN_CHART/msc_gen.py b/openair3/RAL-LTE/RAL-DUMMY/MSCGEN_CHART/msc_gen.py deleted file mode 100755 index e23c1690fa..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/MSCGEN_CHART/msc_gen.py +++ /dev/null @@ -1,344 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Lionel GAUTHIER -# This script is a downgrade of a python script written for the openair stack, generating sequence diagrams charts, displaying -# messages exchanged between LTE access stratum protocol entities. -# This script needs mscgen tool (http://www.mcternan.me.uk/mscgen/). -# -# The aim of this script is to collect some traces from oaisim stack and generate a mscgen script, then generate a sequence diagram -# image (png or jpeg) based on the scripts generated. -# An example of how it can be invoqued: msc_gen.py /tmp/msc_log.txt /tmp/msc_log2.txt msc_logx.txt are input text files, -# They/It are/is generated by the execution of executables in linux user space. May be it is better to operate on log files 'grepped' with MSC: -# ./my_exe.exe | grep \[MSC > /tmp/msc_log1.txt - - -# Now, examples of how to generate a mscgen trace in a C executable: -# -First you have to declare the instance(s) of the protocol(s) that will send or receive messages. -# This is done with the following line: -# [MSC_NEW][system time][protocol_name=instance_name] -# examples: -# printf("[MSC_NEW][%s][MIH-F=%s]\n", getTimeStamp4Log(), g_mihf_id); for declaring a new instance of a protocol entity of type MIH-F -# with an instance name g_mihf_id (of type char*) -# printf("[MSC_NEW][%s][NAS=%s]\n", getTimeStamp4Log(), "nas"); other example. -# This declaration of instances of protocols is mandatory to for this script to work. -# -# -Then for tracing a message you have to log a line following this format: -# [MSC_MSG][system time][source instance_name][--- message_name --->][destination instance_name] -# Note: -# ---> means a message that has been received correctly by destination -# ---x means a message lost by destination -# example -# NOTICE("[MSC_MSG][%s][%s][--- Link_Register.indication\\n%s ---x][%s]\n",getTimeStamp4Log(),g_link_id,g_msc_gen_buf,g_mihf_id); -# - - - - -import sys -import subprocess -import re -import socket -import datetime -import os.path -from datetime import date - -MSCGEN_OUTPUT_TYPE = "png" -MAX_MESSAGES_PER_PAGE = 36 - -SYSTEM_FRAME_NUMBER_STR = 'FRAME' -MODULE_STR = 'MOD' -RADIO_BEARER_STR = 'RB' -MSC_NEW_STR = '[MSC_NEW]' -MSC_MSG_STR = '[MSC_MSG]' -MSC_NBOX_STR = '[MSC_NBOX]' -MSC_BOX_STR = '[MSC_BOX]' -MSC_ABOX_STR = '[MSC_ABOX]' -MSC_RBOX_STR = '[MSC_RBOX]' - -# This dic is filled as follow : g_entities_dic[protocol_instance_name].append(protocol_name) -# where protocol_name can be any of the following MI-USER, MIH-F, RAL, LINK-SAP -g_entities_dic = {} -g_reverse_entities_dic = {} - - -# g_messages is filled with dictionnaries: -# message_dic['entity_src'] = protocol_entity_src -# message_dic['entity_dst'] = protocol_entity_dest -# message_dic['msg'] = message -# message_dic['line_color'] = g_display_color[entity_name] -# message_dic['text_color'] = g_display_color[entity_name] -# message_dic['time'] = system_frame_number -# message_dic['seq_no'] = sequence_number_generator() -# g_messages.append(message_dic) -g_messages = [] - -g_messages_dic = {} - - -# g_display_order_dic is a dictionnary where the order of the display of entities sharing the same module identifier is hardcoded -#MAC and PHY valus have to be above num max radio bearer value -g_display_order_dic = {'MIH-USER': 0, 'MIH-F': 1, 'RAL': 3, 'NAS': 4} - -# Display color of messages of sending entities -g_display_color = {'IP': '\"teal\"', - 'RRC_UE': '\"red\"', - 'MIH-USER': '\"black\"', - 'MIH-F': '\"black\"', - 'RAL': '\"black\"', - 'RAL_M': '\"black\"', - 'RLC_UM': '\"navy\"', - 'RLC_TM': '\"navy\"', - 'NAS': '\"black\"', - 'MAC_eNB': '\"indigo\"', - 'PHY': '\"purple\"'} - - -g_final_display_order_list = [] - -g_sequence_generator = 0 - -def sequence_number_generator(): - global g_sequence_generator - l_seq = g_sequence_generator - g_sequence_generator = g_sequence_generator + 1 - return l_seq - -def parse_log_file_for_discovering_protocol_entities(filename): - global g_entities_dic - global g_entities - global g_messages - global g_final_display_order_list - #open TXT file that contain OAI filtered traces for mscgen - - fhandle = open(filename, 'r') - fcontent = fhandle.read() - fhandle.close() - - # split file content in lines - lines = fcontent.splitlines() - for line in lines: - system_time = 'unknown' - - # if line is a trace of the creation of a new protocol instance - if MSC_NEW_STR in line: - partition = line.rpartition(MSC_NEW_STR) - msc_log_string = partition[2] - #print (" %s " % msc_log_string) - partition = msc_log_string.split('[') - print ("\n\n %s \n" % partition) - #if len(partition) == 2: - - item = partition[1] - item = item.strip() - item = item.strip(']') - system_time = item.split(' ')[-1] - print ("NEW system_time %s " % system_time) - - item = partition[2] - item = item.strip() - item = item.strip(']') - protocol_entity_type = item.split('=')[0] - protocol_entity_name = item.split('=')[-1] - print ("NEW protocol_entity_type %s " % protocol_entity_type) - print ("NEW protocol_entity_name %s " % protocol_entity_name) - - if protocol_entity_name not in g_entities_dic: - g_entities_dic[protocol_entity_name] = protocol_entity_type - - if protocol_entity_type not in g_reverse_entities_dic: - g_reverse_entities_dic[protocol_entity_type] = protocol_entity_name - else: - entity_name_list = g_reverse_entities_dic[protocol_entity_type] - entity_name_list.append(protocol_entity_name) - g_reverse_entities_dic[protocol_entity_type] = entity_name_list - #print (" g_entities_dic[%d][%d].append(%s)" % (module_id_int, radio_bearer_id_int, entity_name_src)) - print (" g_entities_dic= %s\n\n" % (g_entities_dic)) - print (" g_reverse_entities_dic= %s\n\n" % (g_reverse_entities_dic)) - - #g_entities.append(protocol_entity_type) - #print (" %s \n" % protocol_entity) - - - - - -def parse_log_file(filename): - global g_entities_dic - global g_entities - global g_messages - global g_final_display_order_list - #open TXT file that contain OAI filtered traces for mscgen - fhandle = open(filename, 'r') - fcontent = fhandle.read() - fhandle.close() - - # split file content in lines - lines = fcontent.splitlines() - for line in lines: - system_time = 'unknown' - message = 'unknown' - entity_name_src = 'unknown' - entity_name_dest = 'unknown' - - - # if line is a trace of the creation of a new protocol instance - if MSC_MSG_STR in line: - partition = line.strip().rpartition(MSC_MSG_STR) - msc_log_string = partition[2].strip() - print (" %s " % msc_log_string) - partition = msc_log_string.split('[') - print (" %s " % partition) - - #if len(partition) == 9: - message_dic = {} - - system_time = partition[1].strip().split(' ')[-1].strip(']') - message_dic['display_time'] = system_time - seconds_int = int(system_time.split(':')[0]) - micro_seconds_int = int(system_time.split(':')[-1]) - system_time_int = seconds_int*1000000 + micro_seconds_int - system_time=str(system_time_int) - print ('system_time %s' % system_time) - - entity_name_src = partition[2].strip().split(' ')[-1].strip(']') - print ('entity_name_src %s' % entity_name_src) - - message = partition[3].strip().strip(']').strip() - if (message[-1] == 'x') or (message[-1] == 'X'): - message_dic['arc'] = '-x' - elif message[-1] == '>': - message_dic['arc'] = '=>' - message = message.strip('<').strip('>').strip('x').strip('X').strip('-').strip('=').strip() - print ('message %s' % message) - - entity_name_dest = partition[4].strip().split(' ')[-1].strip(']') - print ('entity_name_dest %s' % entity_name_dest) - message_dic['entity_src'] = entity_name_src - message_dic['entity_dst'] = entity_name_dest - message_dic['msg'] = message - message_dic['line_color'] = g_display_color[g_entities_dic[entity_name_src]] - message_dic['text_color'] = g_display_color[g_entities_dic[entity_name_src]] - message_dic['time'] = system_time - #message_dic['seq_no'] = sequence_number_generator() - print ('%s\n\n' % message_dic) - g_messages_dic[system_time_int] = message_dic - #g_messages.append(message_dic) - - -def generate_sorted_message_list(): - first_time_stamp = 0 - for system_time_int in sorted(g_messages_dic.iterkeys()): - if first_time_stamp == 0: - first_time_stamp = system_time_int - message_dic = g_messages_dic[system_time_int] - message_dic['seq_no'] = sequence_number_generator() - message_dic['display_time'] = str(system_time_int - first_time_stamp) - g_messages.append(message_dic) - -def generate_sorted_entity_display_list(): - module_display_order_dic = {} - for entity_name in sorted(g_entities_dic.iterkeys()): - module_display_order_dic[g_display_order_dic[g_entities_dic[entity_name]]] = entity_name - - - print("------------------------------------") - print(" %s " % (module_display_order_dic)) - - for display_priority in sorted(module_display_order_dic.iterkeys()): - g_final_display_order_list.append(module_display_order_dic[display_priority]) - -def msc_chart_write_header(fileP): - global g_final_display_order_list - fileP.write("msc {\n") - fileP.write("width = \"2048\";\n") - - entity_line_list_str = '' - for entity in g_final_display_order_list: - entity_line_list_str = entity_line_list_str + ' ' + entity + ',' - - entity_line_list_str = entity_line_list_str.rstrip().strip(',') - fileP.write(" %s;" % (entity_line_list_str)) - - -def msc_chart_write_footer(fileP): - fileP.write("\n}\n") - -def msc_chart_generate(file_nameP): - global MSCGEN_OUTPUT_TYPE - command_line = "mscgen -T " + MSCGEN_OUTPUT_TYPE + " -i " + file_nameP + "; chmod 777 " +file_nameP + ";" - - print("Command Line: %s " % (command_line)) - fi,fo,fe=os.popen3(command_line) - for i in fe.readlines(): - print "error:",i - -def get_nem_file_descriptor(): - global g_base_file_name - global g_page_index - l_file_name = g_base_file_name + str(g_page_index)+'.txt' - l_file = open(l_file_name, "w", 0777) - return l_file - - -###### MAIN STAR HERE ################# -num_args = len(sys.argv) -if num_args < 2: # the program name and the arguments - # stop the program and print an error message - sys.exit("Must provide at least one file to parse") - -for i in range(1,num_args): - print sys.argv[i] - -for i in range(1,num_args): - parse_log_file_for_discovering_protocol_entities(sys.argv[i]) - -for i in range(1,num_args): - parse_log_file(sys.argv[i]) - -generate_sorted_message_list() -generate_sorted_entity_display_list() - -g_page_index = 0 -g_message_index = 0 -g_message_index_in_current_page = 0 -g_now = datetime.datetime.now() -g_now_formated = g_now.strftime("%Y-%m-%d_%H.%M.%S") -g_currentdir = os.curdir -g_resultdir = os.path.join(g_currentdir, g_now_formated) -os.mkdir(g_resultdir, 0777) -os.chdir(g_resultdir) - -g_base_file_name = 'mih_mscgen_page_' - -g_file = get_nem_file_descriptor() -msc_chart_write_header(g_file) - -for message in g_messages: - - if 'msg' in message: - print ('message %s' % message) - g_file.write(" %s%s%s [ label = \"(%d) T%s %s\", linecolour=%s , textcolour=%s ] ;\n" % (message['entity_src'], message['arc'], message['entity_dst'], message['seq_no'], message['display_time'], message['msg'], message['line_color'], message['text_color'])) - elif 'box' in message: - g_file.write(" %s %s %s [ label = \"%s\", textbgcolour=%s , textcolour=%s ] ;\n" % (message['entity_src'], message['box_type'], message['entity_dst'], message['box'], message['textbg_color'], message['text_color'])) - - g_message_index = g_message_index + 1 - g_message_index_in_current_page = g_message_index_in_current_page + 1 - - if (g_message_index_in_current_page == MAX_MESSAGES_PER_PAGE): - msc_chart_write_footer(g_file) - g_file.close() - msc_chart_generate(g_file.name) - g_page_index = g_page_index + 1 - g_message_index_in_current_page = 0 - - g_file = get_nem_file_descriptor() - msc_chart_write_header(g_file) - - -msc_chart_write_footer(g_file) -g_file.close() -if g_message_index_in_current_page >= 1: - msc_chart_generate(g_file.name) -else: - print("Removing empty seq diagram file: %s " % (g_file.name)) - os.remove(g_file.name) diff --git a/openair3/RAL-LTE/RAL-DUMMY/Makefile b/openair3/RAL-LTE/RAL-DUMMY/Makefile deleted file mode 100755 index e217083fce..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -# lines starting with the pound sign are comments. -# -# These things are options that you might need -# to tweak. - - -# You can modify the below as well, but probably -# won't need to. -INTERFACE_DIR=../INTERFACE-802.21 -INCLUDE_DIR=INCLUDE -SRC_DIR=SRC - -# SVN version -SVNREV = -D'SVN_REV="$(shell svnversion -n .)"' - -CC = gcc - -CFLAGS = -Wall -g -I$(SRC_DIR) -I$(INTERFACE_DIR)/INCLUDE -I$(INCLUDE_DIR) \ - -DMIH_C_MEDIEVAL_EXTENSIONS -DMSCGEN_PYTOOL -DMIH_USER_CONTROL $(SVNREV) - -LDFLAGS = -L$(INTERFACE_DIR)/LIB -lmih_c-802.21 -lrt - -MRAL_OBJS = $(SRC_DIR)/mRALlte_mih_msg.o -MRAL_OBJS += $(SRC_DIR)/mRALlte_thresholds.o -MRAL_OBJS += $(SRC_DIR)/mRALlte_parameters.o -MRAL_OBJS += $(SRC_DIR)/mRALlte_action.o -MRAL_OBJS += $(SRC_DIR)/mRALlte_get.o -MRAL_OBJS += $(SRC_DIR)/mRALlte_subscribe.o -MRAL_OBJS += $(SRC_DIR)/mRALlte_main.o -MRAL_OBJS += $(SRC_DIR)/mRALlte_NAS.o -MRAL_OBJS += $(SRC_DIR)/mRALlte_process.o - -ERAL_OBJS += $(SRC_DIR)/eRALlte_main.o -ERAL_OBJS += $(SRC_DIR)/eRALlte_mih_msg.o -ERAL_OBJS += $(SRC_DIR)/eRALlte_thresholds.o -ERAL_OBJS += $(SRC_DIR)/eRALlte_parameters.o -ERAL_OBJS += $(SRC_DIR)/eRALlte_action.o -ERAL_OBJS += $(SRC_DIR)/eRALlte_subscribe.o -ERAL_OBJS += $(SRC_DIR)/eRALlte_NAS.o -ERAL_OBJS += $(SRC_DIR)/eRALlte_process.o - -OBJS = $(MRAL_OBJS) $(ERAL_OBJS) - -M_RAL_EXE = mRALlteDummy -M_NAS_EXE = NASUEdummy - -E_RAL_EXE = eRALlteDummy -E_NAS_EXE = NASRGdummy - -EXECUTABLE = interface $(M_RAL_EXE) $(M_NAS_EXE) $(E_RAL_EXE) $(E_NAS_EXE) - -# "all" is the default target. Simply make it point to myprogram. - -all: $(EXECUTABLE) - -ral: $(M_RAL_EXE) $(E_RAL_EXE) - -runralwithvalgrind: $(M_RAL_EXE) - -rm -f /tmp/*.txt - -valgrind --leak-check=full --show-reachable=yes --track-origins=yes ./$(M_RAL_EXE) > /tmp/mral.txt - -runral: $(M_RAL_EXE) - -rm -f /tmp/*.txt - -./$(M_RAL_EXE) > /tmp/mral.txt - -interface : - -(cd $(INTERFACE_DIR) && make clean && make) - - -$(M_RAL_EXE) : $(MRAL_OBJS) - $(CC) -o $@ $^ $(LDFLAGS) - -$(M_NAS_EXE) : $(SRC_DIR)/nasUEdummy.o - $(CC) -o $@ $^ - -$(E_RAL_EXE) : $(ERAL_OBJS) - $(CC) -o $@ $^ $(LDFLAGS) - -$(E_NAS_EXE) : $(SRC_DIR)/nasRGdummy.o - $(CC) -o $@ $^ - -%.o: %.c Makefile - @echo Compiling $< - @$(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) -o $@ $< - -clean: - -find . -name "*.o" -delete - -find . -name "*.*~" -delete - -find . -name "*~" -delete - -rm -f $(M_RAL_EXE) $(M_NAS_EXE) - -rm -f $(E_RAL_EXE) $(E_NAS_EXE) diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_NAS.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_NAS.c deleted file mode 100644 index c201a4c27b..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_NAS.c +++ /dev/null @@ -1,921 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include <assert.h> - -#include "eRALlte_proto.h" - -#include "eRALlte_variables.h" -#include "eRALlte_mih_msg.h" -#include "nas_rg_netlink.h" - -#include "MIH_C_Types.h" - -/****************************************************************************/ -/******************* G L O C A L D E F I N I T I O N S *****************/ -/****************************************************************************/ - -extern int g_sockd_nas; // defined in eRALlte_main.c - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -/* Read/write buffer used to receive/send messages from/to the NAS driver */ -static char nas_rg_msg[NAS_RG_NETL_MAXLEN]; - -/* Request messages sent to the NAS driver */ -static struct nas_rg_netl_request *nas_rg_request = (struct nas_rg_netl_request *) nas_rg_msg; - -/* Reply message received from the NAS driver */ -static struct nas_rg_netl_reply *nas_rg_reply = (struct nas_rg_netl_reply *) nas_rg_msg; - -/* Functions used to write messages being sent to the NAS driver */ -static int eRALlte_NAS_write_rb_establish_request(int mt_ix, int ch_ix); -static int eRALlte_NAS_write_rb_release_request(int mt_ix, int ch_ix); -static int eRALlte_NAS_write_cnx_status_request(int mt_ix); -static int eRALlte_NAS_write_rb_list_request(int mt_ix); - -/* Functions used to read messages being received from the NAS driver */ -static int eRALlte_NAS_read_rb_establish_reply(void); -static int eRALlte_NAS_read_rb_release_reply(void); -static int eRALlte_NAS_read_cnx_status_reply(void); -static int eRALlte_NAS_read_rb_list_reply(void); - -static void imei2l2id(const uint8_t* imei, uint32_t* l2id); - -static void _eRALlte_NAS_get_MTs_list(int n_mts, int n_rbs); -static int _eRALlte_NAS_update_MTs_list(int mt_ix, int ch_ix); - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_get_MTs_list() ** - ** ** - ** Description: Gets the list of attached Mobile Terminals. ** - ** (Dummy list: Hard coded for testing purpose) ** - ** ** - ** Inputs: None ** - ** Others: DestIpv6Addr[][] ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -void eRALlte_NAS_get_MTs_list(void) -{ - /* Number of MTs = 2, Number of RBs = 1 */ - _eRALlte_NAS_get_MTs_list(2, 1); // DUMMY -} -static void _eRALlte_NAS_get_MTs_list(int n_mts, int n_rbs) -{ - struct ral_lte_channel *channel; - int mt_ix, ch_ix; - - memcpy(ralpriv->plmn, DefaultPLMN, DEFAULT_PLMN_SIZE); // DUMMY - ralpriv->curr_cellId = RAL_DEFAULT_CELL_ID; // DUMMY - - /* Number of MTs in the list */ - if (n_mts > RAL_MAX_MT) { - /* Should not exceed RAL_MAX_MT */ - n_mts = RAL_MAX_MT; - } - - for (mt_ix=0; mt_ix < n_mts; ++mt_ix) { - ralpriv->mt[mt_ix].ue_id = mt_ix; - // ralpriv->mt[mt_ix].ipv6_l2id[0]= 406787; - // ralpriv->mt[mt_ix].ipv6_l2id[1]= 1351685248 + mt_ix; - ralpriv->mt[mt_ix].num_class = 2; - ralpriv->mt[mt_ix].nas_state = 0x0A; - ralpriv->mt[mt_ix].mt_state = RB_CONNECTED; - - /* Number of Radio Bearers attached to that MT */ - if (n_rbs > RAL_MAX_RB) { - /* Should not exceed RAL_MAX_RB */ - n_rbs = RAL_MAX_RB; - } - - ralpriv->mt[mt_ix].num_rbs = n_rbs; - - for (ch_ix = 0; ch_ix < ralpriv->mt[mt_ix].num_rbs; ch_ix++) { - channel = &ralpriv->mt[mt_ix].radio_channel[ch_ix]; - channel->cnx_id = (RAL_MAX_RB_PER_UE*mt_ix)+ch_ix+1; - channel->rbId = RAL_DEFAULT_RAB_ID; - channel->RadioQoSclass = RAL_DEFAULT_RAB_QoS; - channel->dscpUL = 0; - channel->dscpDL = 0; - channel->nas_state = 16; - channel->status = NAS_CONNECTED; - } - - ralpriv->num_connected_mts++; - - /* MT's IPv6 L2 identifier */ - if (mt_ix < ADDR_MAX) { - memcpy((char *) ralpriv->mt[mt_ix].ipv6_addr, - (char *) DestIpv6Addr[mt_ix], 16); - imei2l2id((uint8_t*) &DestIpv6Addr[mt_ix][8], - (uint32_t*) &ralpriv->mt[mt_ix].ipv6_l2id[0]); - DEBUG(" MT%d initialized : address %d %d\n", mt_ix, - ralpriv->mt[mt_ix].ipv6_l2id[0], - ralpriv->mt[mt_ix].ipv6_l2id[1]); - } - } -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_update_MTs_list() ** - ** ** - ** Description: Updates the list of attached Mobile Terminals. ** - ** (Dummy list: Hard coded for testing purpose) ** - ** ** - ** Inputs: None ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: The index of the MT that has been updated ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -int eRALlte_NAS_update_MTs_list(void) -{ - /* MT index = 2, RB channel index = 0 */ - return _eRALlte_NAS_update_MTs_list(2, 0); // DUMMY -} -static int _eRALlte_NAS_update_MTs_list(int mt_ix, int ch_ix) -{ - struct ral_lte_channel *channel; - - /* MT index */ - if (mt_ix < RAL_MAX_MT) { - ralpriv->mt[mt_ix].ue_id = mt_ix; - ralpriv->mt[mt_ix].num_rbs = 1; - ralpriv->mt[mt_ix].num_class = 2; - ralpriv->mt[mt_ix].nas_state = 0x0A; - ralpriv->mt[mt_ix].mt_state = RB_CONNECTED; - - /* Default RB channel */ - if (ch_ix < RAL_MAX_RB) { - channel = &ralpriv->mt[mt_ix].radio_channel[ch_ix]; - channel->cnx_id = (RAL_MAX_RB_PER_UE*mt_ix)+ch_ix+1; - channel->rbId = RAL_DEFAULT_RAB_ID; - channel->RadioQoSclass = RAL_DEFAULT_RAB_QoS; - channel->dscpUL = 0; - channel->dscpDL = 0; - channel->nas_state = 16; - channel->status = NAS_CONNECTED; - } - - ralpriv->num_connected_mts++; - - ralpriv->mt[mt_ix].ltid = ralpriv->pending_mt.ltid; - - imei2l2id((uint8_t*) &ralpriv->pending_mt.ipv6_addr[8], - (uint32_t*) &ralpriv->mt[mt_ix].ipv6_l2id[0]); - DEBUG (" MT%d initialized : address %d %d\n", mt_ix, - ralpriv->mt[mt_ix].ipv6_l2id[0], - ralpriv->mt[mt_ix].ipv6_l2id[1]); - return mt_ix; - } - - return RAL_MAX_MT; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_process_message() ** - ** ** - ** Description: Processes messages received from the NAS sublayer. ** - ** ** - ** Inputs: None ** - ** Others: g_sockd_nas, nas_rg_msg ** - ** ** - ** Outputs: None ** - ** Return: 0 if the received message has been ** - ** successfully processed; -1 otherwise. ** - ** Others: ** - ** ** - ***************************************************************************/ -int eRALlte_NAS_process_message(void) -{ - int rc = 0; - int n; - - n = recv(g_sockd_nas, nas_rg_msg, NAS_RG_NETL_MAXLEN, 0); - - if (n <= 0) { - if (n < 0) { - ERR(" %s : recv() failed (%d)\n", __FUNCTION__, errno); - } - - rc = -1; - } else if (n != nas_rg_reply->length) { - ERR(" %s : invalid message length %d (should be %d)", __FUNCTION__, - n, nas_rg_reply->length); - rc = -1; - } - - if (!rc) { - rc = -1; - - switch (nas_rg_reply->type) { - /* - * Process Radio Bearer establish reply message - */ - case NAS_RG_MSG_RB_ESTABLISH_REPLY: - DEBUG(" NAS_RG_MSG_RB_ESTABLISH_REPLY received from NAS (%d)\n", nas_rg_reply->length); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][nas][--- NAS_RG_MSG_RB_ESTABLISH_REPLY --->][%s]\n", - getTimeStamp4Log(), g_link_id); -#endif - rc = eRALlte_NAS_read_rb_establish_reply(); - break; - - /* - * Process Radio Bearer release reply message - */ - case NAS_RG_MSG_RB_RELEASE_REPLY: - DEBUG(" NAS_RG_MSG_RB_RELEASE_REPLY received from NAS (%d)\n", nas_rg_reply->length); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][nas][--- NAS_RG_MSG_RB_RELEASE_REPLY --->][%s]\n", - getTimeStamp4Log(), g_link_id); -#endif - rc = eRALlte_NAS_read_rb_release_reply(); - break; - - case NAS_RG_MSG_MT_MCAST_JOIN_REP: - DEBUG(" NAS_RG_MSG_MT_MCAST_JOIN_REP received "); - break; - - case NAS_RG_MSG_MT_MCAST_LEAVE_REP: - DEBUG(" NAS_RG_MSG_MT_MCAST_LEAVE_REP received "); - break; - - /* - * Process connection status reply message - */ - case NAS_RG_MSG_CNX_STATUS_REPLY: - DEBUG(" NAS_RG_MSG_CNX_STATUS_REPLY received from NAS (%d)\n", nas_rg_reply->length); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][nas][--- NAS_RG_MSG_CNX_STATUS_REPLY --->][%s]\n", - getTimeStamp4Log(), g_link_id); -#endif - rc = eRALlte_NAS_read_cnx_status_reply(); - break; - - /* - * Process Radio Bearer list reply message - */ - case NAS_RG_MSG_RB_LIST_REPLY: - DEBUG(" NAS_RG_MSG_RB_LIST_REPLY received from NAS (%d)\n", nas_rg_reply->length); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][nas][--- NAS_RG_MSG_RB_LIST_REPLY --->][%s]\n", - getTimeStamp4Log(), g_link_id); -#endif - rc = eRALlte_NAS_read_rb_list_reply(); - break; - - case NAS_RG_MSG_STATISTIC_REPLY: - DEBUG(" NAS_RG_MSG_STATISTIC_REPLY received\n"); - break; - - case NAS_RG_MSG_MEASUREMENT_REPLY: - DEBUG(" NAS_RG_MSG_MEASUREMENT_REPLY received\n"); - break; - - default: - WARNING(" %s : invalid message Type %d\n", - __FUNCTION__, nas_rg_reply->type); - break; - } - - } - - return rc; -} - -#ifdef RAL_REALTIME -/**************************************************************************** - ** ** - ** Name: TQAL_process_NAS_message() ** - ** ** - ** Description: Sends messages to the NAS sublayer. ** - ** ** - ** Inputs: ioctl_obj: ioctl object identifier ** - ** ioctl_cmd: ioctl command identifier ** - ** mt_ix: Mobile Terminal index ** - ** ch_ix: Radio Bearer channel index ** - ** Others: g_sockd_nas, nas_rg_msg, nas_rg_request ** - ** ** - ** Outputs: None ** - ** Return: 0 if the message has been successfully ** - ** sent to the NAS driver; -1 otherwise. ** - ** Others: nas_rg_msg ** - ** ** - ***************************************************************************/ -int TQAL_process_NAS_message(int ioctl_obj, int ioctl_cmd, - int mt_ix, int ch_ix) -{ - int rc = -1; - char msg_name[64]; - - memset(nas_rg_msg, 0, NAS_RG_NETL_MAXLEN); - - switch (ioctl_obj) { - case IO_OBJ_STATS: - /* - * Statistics command - */ - break; - - case IO_OBJ_CNX: - - /* - * Connexion command - */ - switch (ioctl_cmd) { - case IO_CMD_LIST: - strncpy(msg_name, "NAS_RG_MSG_CNX_STATUS_REQUEST", 64); - rc = eRALlte_NAS_write_cnx_status_request(mt_ix); - break; - - default: - ERR(" %s : invalid ioctl command %d for object %d\n", - __FUNCTION__, ioctl_cmd, ioctl_obj); - break; - } - - break; - - case IO_OBJ_RB: - - /* - * Radio Bearer command - */ - switch (ioctl_cmd) { - case IO_CMD_ADD: - strncpy(msg_name, "NAS_RG_MSG_RB_ESTABLISH_REQUEST", 64); - rc = eRALlte_NAS_write_rb_establish_request(mt_ix, ch_ix); - break; - - case IO_CMD_DEL: - strncpy(msg_name, "NAS_RG_MSG_RB_RELEASE_REQUEST", 64); - rc = eRALlte_NAS_write_rb_release_request(mt_ix, ch_ix); - break; - - case IO_CMD_LIST: - strncpy(msg_name, "NAS_RG_MSG_RB_LIST_REQUEST", 64); - rc = eRALlte_NAS_write_rb_list_request(mt_ix); - break; - - default: - ERR(" %s : invalid ioctl command %d for object %d\n", - __FUNCTION__, ioctl_cmd, ioctl_obj); - break; - } - - break; - - case IO_OBJ_MC: - - /* - * Multicast command - */ - switch (ioctl_cmd) { - case IO_CMD_ADD: - break; - - case IO_CMD_DEL: - break; - - default: - ERR(" %s : invalid ioctl command %d for object %d\n", - __FUNCTION__, ioctl_cmd, ioctl_obj); - break; - } - - break; - - default: - ERR(" %s : invalid ioctl object %d\n", __FUNCTION__, ioctl_obj); - break; - } - - if (!rc) { - rc = send(g_sockd_nas, nas_rg_msg, nas_rg_request->length, 0); - - if (rc < 0) { - ERR(": failed to send %s (%d)\n", msg_name, errno); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- %s ---x][nas]\n", - getTimeStamp4Log(), g_link_id, msg_name); -#endif - } else { - DEBUG (" %s sent to NAS (%d)\n", msg_name, nas_rg_request->length); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- %s --->][nas]\n", - getTimeStamp4Log(), g_link_id, msg_name); -#endif - } - } - - return rc; -} -#endif - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_send_rb_establish_request() ** - ** ** - ** Description: Sends Radio Bearer establish request to the NAS driver. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** ch_ix: Radio bearer channel index ** - ** Others: g_sockd_nas, nas_rg_msg, nas_rg_request ** - ** ** - ** Outputs: None ** - ** Return: -1 if the request message has not been ** - ** successfully sent to the NAS driver. ** - ** Otherwise, the number of bytes actually ** - ** sent to the NAS driver. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRALlte_NAS_send_rb_establish_request(int mt_ix, int ch_ix) -{ - int rc = eRALlte_NAS_write_rb_establish_request(mt_ix, ch_ix); - - if (!rc) { - rc = send(g_sockd_nas, nas_rg_msg, nas_rg_request->length, 0); - - if (rc < 0) { - ERR(": failed to send NAS_RG_MSG_RB_ESTABLISH_REQUEST (%d)\n", errno); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- NAS_RG_MSG_RB_ESTABLISH_REQUEST ---x][nas]\n", getTimeStamp4Log(), g_link_id); -#endif - } else { - DEBUG (" NAS_RG_MSG_RB_ESTABLISH_REQUEST sent to NAS (%d)\n", nas_rg_request->length); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- NAS_RG_MSG_RB_ESTABLISH_REQUEST --->][nas]\n", getTimeStamp4Log(), g_link_id); -#endif - } - } - - return rc; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_send_rb_release_request() ** - ** ** - ** Description: Sends Radio Bearer release request to the NAS driver. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** ch_ix: Radio bearer channel index ** - ** Others: g_sockd_nas, nas_rg_msg, nas_rg_request ** - ** ** - ** Outputs: None ** - ** Return: -1 if the request message has not been ** - ** successfully sent to the NAS driver. ** - ** Otherwise, the number of bytes actually ** - ** sent to the NAS driver. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRALlte_NAS_send_rb_release_request(int mt_ix, int ch_ix) -{ - int rc = eRALlte_NAS_write_rb_release_request(mt_ix, ch_ix); - - if (!rc) { - rc = send(g_sockd_nas, nas_rg_msg, nas_rg_request->length, 0); - - if (rc < 0) { - ERR(": failed to send NAS_RG_MSG_RB_RELEASE_REQUEST (%d)\n", errno); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- NAS_RG_MSG_RB_RELEASE_REQUEST ---x][nas]\n", getTimeStamp4Log(), g_link_id); -#endif - } else { - DEBUG (" NAS_RG_MSG_RB_RELEASE_REQUEST sent to NAS (%d)\n", nas_rg_request->length); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- NAS_RG_MSG_RB_RELEASE_REQUEST --->][nas]\n", getTimeStamp4Log(), g_link_id); -#endif - } - } - - return rc; -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_write_rb_establish_request() ** - ** ** - ** Description: Writes Radio Bearer establish request to be sent to the ** - ** NAS driver. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** ch_ix: Radio bearer channel index ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: Always returns 0 ** - ** Others: nas_rg_request, ralpriv ** - ** ** - ***************************************************************************/ -static int eRALlte_NAS_write_rb_establish_request(int mt_ix, int ch_ix) -{ - struct ral_lte_channel *currChannel; - struct nas_rg_msg_rb_establish_request* rb_est_req = &(nas_rg_request->tqalNASPrimitive.rb_est_req); - - nas_rg_request->type = NAS_RG_MSG_RB_ESTABLISH_REQUEST; - nas_rg_request->length = sizeof(struct nas_rg_netl_hdr) + sizeof(struct nas_rg_msg_rb_establish_request); - - if (mt_ix == RAL_MAX_MT) { - currChannel = &(ralpriv->mcast.radio_channel); - } else { - currChannel = &(ralpriv->mt[mt_ix].radio_channel[ch_ix]); - } - - rb_est_req->cnxid = currChannel->cnx_id; - rb_est_req->RBParms.rbId = currChannel->rbId; - rb_est_req->RBParms.QoSclass = currChannel->RadioQoSclass; - rb_est_req->RBParms.dscp = currChannel->dscpDL; - rb_est_req->mcast_flag = currChannel->multicast; - - ralpriv->pending_req_mt_ix = mt_ix; - ralpriv->pending_req_ch_ix = ch_ix; - - return 0; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_read_rb_establish_reply() ** - ** ** - ** Description: Reads Radio Bearer establish reply received from the NAS ** - ** driver. ** - ** Returns a Link_Up.indication to the MIH-F. ** - ** ** - ** Inputs: None ** - ** Others: nas_rg_reply ** - ** ** - ** Outputs: None ** - ** Return: 0 if the message type is valid, ** - ** -1 otherwise. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -static int eRALlte_NAS_read_rb_establish_reply(void) -{ - if (nas_rg_reply->type == NAS_RG_MSG_RB_ESTABLISH_REPLY) { - struct ral_lte_channel *currChannel; - struct nas_rg_msg_rb_establish_reply* rb_est_rep = &(nas_rg_reply->tqalNASPrimitive.rb_est_rep); - int mt_ix, ch_ix; - - MIH_C_LINK_TUPLE_ID_T* ltid; - int is_unicast = eRALlte_process_find_channel(rb_est_rep->cnxid, - &mt_ix, &ch_ix); - - /* Read received parameters */ - if (is_unicast) { - ralpriv->mt[mt_ix].ue_id = rb_est_rep->ue_id; - currChannel = &(ralpriv->mt[mt_ix].radio_channel[ch_ix]); - ltid = &ralpriv->mt[mt_ix].ltid; - } else { - currChannel = &(ralpriv->mcast.radio_channel); - ltid = &ralpriv->mcast.ltid; - } - - /* Check channel status */ - if (rb_est_rep->result == NAS_CONNECTED) { - ralpriv->pending_req_status = MIH_C_STATUS_SUCCESS; - currChannel->cnx_id = rb_est_rep->cnxid; - currChannel->rbId = rb_est_rep->RBParms.rbId; - currChannel->RadioQoSclass = rb_est_rep->RBParms.QoSclass; - currChannel->dscpDL = rb_est_rep->RBParms.dscp; - currChannel->status = rb_est_rep->result; - } else { - ralpriv->pending_req_status = MIH_C_STATUS_REJECTED; - /* Clean radio resources */ - eRALlte_process_clean_channel(currChannel); - } - - /* Send Link-Up.indication to the MIH-F */ - if (ralpriv->pending_req_status != MIH_C_STATUS_REJECTED) { - eRALlte_send_link_up_indication(&ralpriv->pending_req_transaction_id, ltid, NULL, NULL, NULL, NULL); - } - - ralpriv->pending_req_mt_ix = -1; - ralpriv->pending_req_ch_ix = -1; - ralpriv->pending_req_transaction_id = 0; - - return 0; - } - - return -1; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_write_rb_release_request() ** - ** ** - ** Description: Writes Radio Bearer release request to be sent to the NAS ** - ** driver. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** ch_ix: Radio Bearer channel index ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: Always returns 0 ** - ** Others: nas_rg_request ** - ** ** - ***************************************************************************/ -static int eRALlte_NAS_write_rb_release_request(int mt_ix, int ch_ix) -{ - struct ral_lte_channel *currChannel; - struct nas_rg_msg_rb_release_request* rb_rel_req = &(nas_rg_request->tqalNASPrimitive.rb_rel_req); - - nas_rg_request->type = NAS_RG_MSG_RB_RELEASE_REQUEST; - nas_rg_request->length = sizeof(struct nas_rg_netl_hdr) + sizeof(struct nas_rg_msg_rb_release_request); - - if (mt_ix == RAL_MAX_MT) { - currChannel = &(ralpriv->mcast.radio_channel); - rb_rel_req->ue_id = RAL_MAX_MT; - } else { - currChannel = &(ralpriv->mt[mt_ix].radio_channel[ch_ix]); - rb_rel_req->ue_id = ralpriv->mt[mt_ix].ue_id; - } - - rb_rel_req->cnxid = currChannel->cnx_id; - rb_rel_req->rbId = currChannel->rbId; - - ralpriv->pending_req_mt_ix = mt_ix; - ralpriv->pending_req_ch_ix = ch_ix; - - return 0; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_read_rb_release_reply() ** - ** ** - ** Description: Reads Radio Bearer release reply received from the NAS ** - ** driver. ** - ** Returns a Link_Down.indication to the MIH-F. ** - ** ** - ** Inputs: None ** - ** Others: nas_rg_reply ** - ** ** - ** Outputs: None ** - ** Return: 0 if the message type is valid, ** - ** -1 otherwise. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -static int eRALlte_NAS_read_rb_release_reply(void) -{ - if (nas_rg_reply->type == NAS_RG_MSG_RB_RELEASE_REPLY) { - struct ral_lte_channel *currChannel; - struct nas_rg_msg_rb_release_reply* rb_rel_rep = &(nas_rg_reply->tqalNASPrimitive.rb_rel_rep); - int mt_ix, ch_ix; - MIH_C_LINK_DN_REASON_T reason_code = MIH_C_LINK_DOWN_REASON_EXPLICIT_DISCONNECT; - MIH_C_LINK_TUPLE_ID_T* ltid; - - int is_unicast = eRALlte_process_find_channel(rb_rel_rep->cnxid, - &mt_ix, &ch_ix); - - /* Read received parameters */ - if (is_unicast) { - assert (rb_rel_rep->ue_id == ralpriv->mt[mt_ix].ue_id); - currChannel = &(ralpriv->mt[mt_ix].radio_channel[ch_ix]); - ltid = &ralpriv->mt[mt_ix].ltid; - } else { - assert (rb_rel_rep->ue_id == RAL_MAX_MT); - currChannel = &(ralpriv->mcast.radio_channel); - ltid = &ralpriv->mcast.ltid; - } - - /* Check channel status */ - if (rb_rel_rep->result == NAS_DISCONNECTED) { - ralpriv->pending_req_status = MIH_C_STATUS_SUCCESS; - } else { - ralpriv->pending_req_status = MIH_C_STATUS_REJECTED; - } - - /* Clean radio resources */ - eRALlte_process_clean_channel(currChannel); - - /* Send Link-Down.indication to the MIH-F */ - if (ralpriv->pending_req_status != MIH_C_STATUS_REJECTED) { - eRALlte_send_link_down_indication(&ralpriv->pending_req_transaction_id, ltid, NULL, &reason_code); - } - - ralpriv->pending_req_mt_ix = -1; - ralpriv->pending_req_ch_ix = -1; - ralpriv->pending_req_transaction_id = 0; - - return 0; - } - - return -1; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_write_cnx_status_request() ** - ** ** - ** Description: Writes connection status request to be sent to the NAS ** - ** driver. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: Always returns 0 ** - ** Others: nas_rg_request ** - ** ** - ***************************************************************************/ -static int eRALlte_NAS_write_cnx_status_request(int mt_ix) -{ - struct nas_rg_msg_cnx_status_request* cnx_stat_req = &(nas_rg_request->tqalNASPrimitive.cnx_stat_req); - - nas_rg_request->type = NAS_RG_MSG_CNX_STATUS_REQUEST; - nas_rg_request->length = sizeof(struct nas_rg_netl_hdr) + sizeof(struct nas_rg_msg_cnx_status_request); - - /* Connection status is requested for MT unicast only */ - assert (mt_ix < RAL_MAX_MT); - cnx_stat_req->ue_id = ralpriv->mt[mt_ix].ue_id; - return 0; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_read_cnx_status_reply() ** - ** ** - ** Description: Reads connection status reply received from the NAS ** - ** driver. ** - ** ** - ** Inputs: None ** - ** Others: nas_rg_reply ** - ** ** - ** Outputs: None ** - ** Return: 0 if the message type is valid, ** - ** -1 otherwise. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -static int eRALlte_NAS_read_cnx_status_reply(void) -{ - if (nas_rg_reply->type == NAS_RG_MSG_CNX_STATUS_REPLY) { - struct nas_rg_msg_cnx_status_reply* cnx_stat_rep = &(nas_rg_reply->tqalNASPrimitive.cnx_stat_rep); - - int mt_ix = cnx_stat_rep->ue_id; - - /* Connection status has been requested for MT unicast only */ - assert (mt_ix < RAL_MAX_MT); - assert (mt_ix == ralpriv->mt[mt_ix].ue_id); - - /* Read MT connection establishment status */ - ralpriv->mt[mt_ix].mt_state = cnx_stat_rep->status; // TODO ??? - return 0; - } - - return -1; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_write_rb_list_request() ** - ** ** - ** Description: Writes Radio Bearer list request to be sent to the NAS ** - ** driver. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: Always returns 0 ** - ** Others: nas_rg_request ** - ** ** - ***************************************************************************/ -static int eRALlte_NAS_write_rb_list_request(int mt_ix) -{ - struct nas_rg_msg_rb_list_request* rb_list_req = &(nas_rg_request->tqalNASPrimitive.rb_list_req); - - nas_rg_request->type = NAS_RG_MSG_RB_LIST_REQUEST; - nas_rg_request->length = sizeof(struct nas_rg_netl_hdr) + sizeof(struct nas_rg_msg_rb_list_request); - - /* Radio Bearer list is requested for MT unicast only */ - assert (mt_ix < RAL_MAX_MT); - rb_list_req->ue_id = ralpriv->mt[mt_ix].ue_id; - return 0; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_NAS_read_rb_list_reply() ** - ** ** - ** Description: Reads Radio Bearer list reply received from the NAS ** - ** driver. ** - ** ** - ** Inputs: None ** - ** Others: nas_rg_reply ** - ** ** - ** Outputs: None ** - ** Return: 0 if the message type is valid, ** - ** -1 otherwise. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -static int eRALlte_NAS_read_rb_list_reply(void) -{ - if (nas_rg_reply->type == NAS_RG_MSG_RB_LIST_REPLY) { - struct ral_lte_channel *currChannel; - struct nas_rg_msg_rb_list_reply* rb_list_rep = &(nas_rg_reply->tqalNASPrimitive.rb_list_rep); - - int mt_ix = rb_list_rep->ue_id; - int ch_ix; - - /* Radio Bearer list has been requested for MT unicast only */ - assert (mt_ix < RAL_MAX_MT); - assert (mt_ix == ralpriv->mt[mt_ix].ue_id); - - /* Read Radio Bearer channel data */ - assert (rb_list_rep->num_rb <= NAS_RG_NETL_MAX_RABS); - ralpriv->mt[mt_ix].num_rbs = rb_list_rep->num_rb; - - for (ch_ix = 0; ch_ix < ralpriv->mt[mt_ix].num_rbs; ch_ix++) { - currChannel = &ralpriv->mt[mt_ix].radio_channel[ch_ix]; - currChannel->multicast = 0; - currChannel->rbId = rb_list_rep->RBList[ch_ix].rbId; - currChannel->RadioQoSclass = rb_list_rep->RBList[ch_ix].QoSclass; - currChannel->dscpUL = rb_list_rep->RBList[ch_ix].dscp; // TODO ??? - currChannel->dscpDL = rb_list_rep->RBList[ch_ix].dscp; // TODO ??? - } - - return 0; - } - - return -1; -} - -/**************************************************************************** - ** ** - ** Name: imei2l2id() ** - ** ** - ** Description: Converts IMEI to Layer 2 identifier ** - ** ** - ** Inputs: imei IMEI identifier ** - ** Others: None ** - ** ** - ** Outputs: l2id Layer 2 identifier ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -static void imei2l2id(const uint8_t* imei, uint32_t* l2id) -{ - if ( !(imei) || !(l2id) ) { - ERR(" %s : input parameter is NULL\n", __FUNCTION__); - return; - } - - l2id[0] = imei[0]+256 *(imei[1]+256*(imei[2]+256*(imei[3]))); - l2id[1] = imei[4]+256 *(imei[5]+256*(imei[6]+256*(imei[7]))); -} - diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_action.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_action.c deleted file mode 100644 index 24bad1909d..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_action.c +++ /dev/null @@ -1,890 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include <assert.h> - -#include "eRALlte_action.h" - -#include "eRALlte_mih_msg.h" -#include "eRALlte_variables.h" -#include "eRALlte_constants.h" -#include "eRALlte_proto.h" - -/****************************************************************************/ -/******************* G L O C A L D E F I N I T I O N S *****************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -static MIH_C_LINK_ACTION_T g_link_action; - -static const char* g_link_action_type_str[] = { - "MIH_C_LINK_AC_TYPE_NONE", - "MIH_C_LINK_AC_TYPE_LINK_DISCONNECT", - "MIH_C_LINK_AC_TYPE_LINK_LOW_POWER", - "MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN", - "MIH_C_LINK_AC_TYPE_LINK_POWER_UP", -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - "MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR", - "MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES", - "MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES" -#endif -}; - -static int _eRALlte_action_is_in_progress(MIH_C_STATUS_T* status, - MIH_C_LINK_AC_RESULT_T* ac_status, - MIH_C_LINK_AC_TYPE_T action); - -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -static MIH_C_LINK_AC_RESULT_T _eRALlte_action_link_flow_attr(void); -static MIH_C_LINK_AC_RESULT_T _eRALlte_action_link_activate_resources(void); -static MIH_C_LINK_AC_RESULT_T _eRALlte_action_link_deactivate_resources(void); - -/* - * --------------------------------------------------------------------------- - * Flow identifier management: - * Radio Bearer data flows are identified by a source address, a destination - * address and a port number for a particular IP transport protocol (UDP, - * TCP). A private data structure is used to map upper-layer flow identifiers - * to lower-layer RB channel identifiers. It is handled by private functions. - * --------------------------------------------------------------------------- - */ -/* Structure of the destination data flow */ -struct Data_flow { - unsigned char addr[16]; // IP address - unsigned int l2id[2]; // L2 identifier - unsigned int port; // IP port identifier - int proto; // IP protocol - int cnxid; // Data flow identifier -}; -typedef struct { - int n_flows; -#define ACTION_MAX_FLOW ((RAL_MAX_MT)*(RAL_MAX_RB)) - struct Data_flow flow [ACTION_MAX_FLOW]; - int flow_id [ACTION_MAX_FLOW]; //added TEMP MW 23/05/13 -} eRALlte_action_DataFlowList_t; - -static eRALlte_action_DataFlowList_t g_flows = {}; - -static int _eRALlte_action_set_channel_id (MIH_C_FLOW_ID_T* flowId, int cnxid); -static int _eRALlte_action_get_channel_id (MIH_C_FLOW_ID_T* flowId, int* cnxid); -static int _eRALlte_action_del_channel_id (int fix); -#endif // MIH_C_MEDIEVAL_EXTENSIONS - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRALlte_action_request() ** - ** ** - ** Description: Processes the Link_Action.request message and sends a ** - ** Link_Action.confirm message to the MIHF. ** - ** ** - ** Inputs: msgP: Pointer to the received message ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_link_action ** - ** ** - ***************************************************************************/ -void eRALlte_action_request(MIH_C_Message_Link_Action_request_t* msgP) -{ - MIH_C_STATUS_T status; - MIH_C_LINK_AC_TYPE_T link_action_type; - MIH_C_LINK_AC_RESULT_T link_action_result; - int link_action_done = 0; - - memcpy(&g_link_action, &msgP->primitive.LinkAction, sizeof(MIH_C_LINK_ACTION_T)); - - status = MIH_C_STATUS_SUCCESS; - link_action_type = msgP->primitive.LinkAction.link_ac_type; - link_action_result = MIH_C_LINK_AC_RESULT_SUCCESS; - - /* - * Read link action attributs - * -------------------------- - */ - if (msgP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_LINK_SCAN) { - /* - * Link scan operation request - Not supported by the network side: - * No measurements - */ - DEBUG(" ACTION ATTRIBUTE MIH_C_BIT_LINK_AC_ATTR_LINK_SCAN: REFUSED\n"); - link_action_result = MIH_C_LINK_AC_RESULT_REFUSED; - eRALlte_send_link_action_confirm(&msgP->header.transaction_id, - &status, - NULL, - &link_action_result); - } - - if (msgP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_LINK_RES_RETAIN) { - /* - * Link resource retain operation request - Not supported by the - * network side. - */ - DEBUG(" ACTION ATTRIBUTE MIH_C_BIT_LINK_AC_ATTR_LINK_RES_RETAIN: REFUSED\n"); - link_action_result = MIH_C_LINK_AC_RESULT_REFUSED; - eRALlte_send_link_action_confirm(&msgP->header.transaction_id, - &status, - NULL, - &link_action_result); - } - - if (msgP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_DATA_FWD_REQ) { - /* - * Data forward operation request - Not supported by the network side. - */ - DEBUG(" ACTION ATTRIBUTE MIH_C_BIT_LINK_AC_ATTR_DATA_FWD_REQ: REFUSED\n"); - link_action_result = MIH_C_LINK_AC_RESULT_REFUSED; - eRALlte_send_link_action_confirm(&msgP->header.transaction_id, - &status, - NULL, - &link_action_result); - } - - /* - * Read link action request - * ------------------------ - * Requested actions that are not supported or currently in progress - * are refused. - */ - if (_eRALlte_action_is_in_progress(&status, - &link_action_result, - link_action_type)) { - DEBUG(" Link action request %s is not supported or currently in progress\n", g_link_action_type_str[link_action_type]); - } else { - DEBUG(" %s ACTION REQUESTED: %s\n", __FUNCTION__, g_link_action_type_str[link_action_type]); - - switch (link_action_type) { - case MIH_C_LINK_AC_TYPE_NONE: - DEBUG(" NO ACTION\n"); - break; - -#ifdef MIH_C_MEDIEVAL_EXTENSIONS - - case MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR: - /* - * Provide the mark and multicast configuration to be set up - * for the data flow - */ - ralpriv->pending_req_ac_result = _eRALlte_action_link_flow_attr(); - link_action_done = 1; - break; - - case MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES: - /* - * Configure and activate a data flow - */ - ralpriv->pending_req_ac_result = _eRALlte_action_link_activate_resources(); - link_action_done = 1; - break; - - case MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES: - /* - * Deactivate a previously activated data flow - */ - ralpriv->pending_req_ac_result = _eRALlte_action_link_deactivate_resources(); - link_action_done = 1; - break; -#endif // MIH_C_MEDIEVAL_EXTENSIONS - - case MIH_C_LINK_AC_TYPE_LINK_DISCONNECT: - - /* - * Disconnect the link connection directly - */ - case MIH_C_LINK_AC_TYPE_LINK_LOW_POWER: - - /* - * Cause the link to adjust its battery power level to be - * low power consumption - Not supported by the network side - */ - case MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN: - - /* - * Cause the link to power down and turn off the radio - * - Not supported by the network side - */ - case MIH_C_LINK_AC_TYPE_LINK_POWER_UP: - /* - * Cause the link to power up and establish L2 connectivity. - * For UMTS link type, power up lower layers and establish - * PDP context - Not supported by the network side - */ - DEBUG(" REFUSED\n"); - link_action_result = MIH_C_LINK_AC_RESULT_REFUSED; - break; - - default: - ERR(" %s Invalid LinkAction.link_ac_type %d\n", - __FUNCTION__, link_action_type); - status = MIH_C_STATUS_UNSPECIFIED_FAILURE; - } - } - - /* Return link action confirmation to the MIH-F */ - if (link_action_done) { - ralpriv->pending_req_transaction_id = msgP->header.transaction_id; - ralpriv->pending_req_status = MIH_C_STATUS_SUCCESS; - eRALlte_send_link_action_confirm(&ralpriv->pending_req_transaction_id, - &ralpriv->pending_req_status, - NULL, - &ralpriv->pending_req_ac_result); - } else if (status == MIH_C_STATUS_SUCCESS) { - eRALlte_send_link_action_confirm(&msgP->header.transaction_id, - &status, - NULL, - &link_action_result); - } else { - eRALlte_send_link_action_confirm(&msgP->header.transaction_id, - &status, - NULL, - NULL); - } - - ralpriv->pending_req_action = 0; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_action_save_flow_id() ** - ** ** - ** Description: Save connection identifier and data of the specified data ** - ** flow into the list of active data flows. ** - ** ** - ** Inputs: flowId: The data flow identifier ** - ** cnxid: The connection identifier ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: The index of the specified data flow in ** - ** the list of active data flows. ** - ** -1 if the list is full. ** - ** Others: None ** - ** ** - ***************************************************************************/ -extern int eRALlte_action_save_flow_id(MIH_C_FLOW_ID_T* flowId, int cnxid) -{ - return _eRALlte_action_set_channel_id(flowId, cnxid); -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/**************************************************************************** - ** Name: eRALlte_action_set_channel_id() ** - ** ** - ** Description: Set the Connection identifier and store data of the ** - ** specified data flow in the list of active data flows. ** - ** Inputs: flowId: The data flow identifier ** - ** cnxid: The connection identifier ** - ** Outputs: None ** - ** Return: The index of the specified data flow in ** - ** the list of active data flows. ** - ** -1 if the list is full. ** - ***************************************************************************/ -static int _eRALlte_action_set_channel_id (MIH_C_FLOW_ID_T* flowId, int cnxid) -{ - char addr[128]; - //char port[8]; - int f_ix; - - assert(cnxid != 0); - - for (f_ix = 0; f_ix < ACTION_MAX_FLOW; f_ix++) { - if (g_flows.flow[f_ix].cnxid > 0) continue; - - g_flows.flow[f_ix].cnxid = cnxid; - g_flows.flow_id[f_ix] = (int) flowId; - g_flows.n_flows += 1; - - // Modified Michelle - memcpy((char*)&(DestIpv6Addr[0][16]), addr, 16); - eRALlte_process_mt_addr_to_l2id(&g_flows.flow[f_ix].addr[8], - &g_flows.flow[f_ix].l2id[0]); - - /* MIH_C_TRANSPORT_ADDR_VALUE2String(&flowId->dest_addr.ip_addr.address, addr); - memcpy((char*)&(g_flows.flow[f_ix].addr), addr, 16); - eRALlte_process_mt_addr_to_l2id(&g_flows.flow[f_ix].addr[8], - &g_flows.flow[f_ix].l2id[0]); - MIH_C_PORT2String(&flowId->dest_addr.port, port); - g_flows.flow[f_ix].port = strtol(port, (char**) NULL, 16); - g_flows.flow[f_ix].proto = flowId->transport_protocol;*/ - return f_ix; - } - - return (-1); -} - -/**************************************************************************** - ** Name: eRALlte_action_get_channel_id() ** - ** ** - ** Description: Returns the Connection identifier of the specified data ** - ** flow. ** - ** Inputs: flowId: The data flow identifier ** - ** Others: None ** - ** Outputs: cnxid: The connection identifier allocated to the ** - ** specified data flow. ** - ** Return: The index of the specified data flow in ** - ** the list of active data flows. ** - ** -1 if no any connection identifier exists ** - ** for the specified data flow. ** - ** Others: None ** - ***************************************************************************/ -static int _eRALlte_action_get_channel_id (MIH_C_FLOW_ID_T* flowId, int* cnxid) -{ - //char addr[128]; - //char port[8]; - //unsigned int dp; - int f_ix; - - // MIH_C_TRANSPORT_ADDR_VALUE2String(&flowId->dest_addr.ip_addr.address, addr); - // MIH_C_PORT2String(&flowId->dest_addr.port, port); - // dp = strtol(port, (char**) NULL, 16); - - for (f_ix = 0; f_ix < ACTION_MAX_FLOW; f_ix++) { - /* if (!eRALlte_process_cmp_mt_addr((const char*)addr, (const char*)g_flows.flow[f_ix].l2id)) continue; - if (g_flows.flow[f_ix].port != dp) continue; - if (g_flows.flow[f_ix].proto != flowId->transport_protocol) continue;*/ - if (g_flows.flow_id[f_ix] != *flowId) continue; - - *cnxid = g_flows.flow[f_ix].cnxid; - return f_ix; - } - - return (-1); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_action_del_channel_id() ** - ** ** - ** Description: Remove the data flow stored at the specified index in the ** - ** list of active data flows. ** - ** ** - ** Inputs: fix: Index of the data flow in the list ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: The number of the remaining data flows in ** - ** the list. ** - ** -1 if the specified index is out of the ** - ** boundary of the list. ** - ** Others: None ** - ** ** - ***************************************************************************/ -static int _eRALlte_action_del_channel_id (int fix) -{ - if (fix < ACTION_MAX_FLOW) { - g_flows.n_flows -= 1; - memset (&g_flows.flow[fix], 0, sizeof (struct Data_flow)); - return g_flows.n_flows; - } - - return (-1); -} - -/**************************************************************************** - ** ** - ** Name: _eRALlte_action_is_in_progress() ** - ** ** - ** Description: Checks if an action request is supported and whether it ** - ** is currently in progress. ** - ** ** - ** Inputs: action: Type of link action ** - ** Others: g_link_action, ralpriv ** - ** ** - ** Outputs: status: MIH request status ** - ** ac_status: Action request status ** - ** Return: 1 if the request is not supported or is ** - ** currently in progress and the resource is ** - ** already in the required state. 0 otherwise.** - ** Others: None ** - ** ** - ***************************************************************************/ -static int _eRALlte_action_is_in_progress(MIH_C_STATUS_T* status, - MIH_C_LINK_AC_RESULT_T* ac_status, - MIH_C_LINK_AC_TYPE_T action) -{ - /* Check whether the action link command is supported */ - if (!(ralpriv->mih_supported_link_command_list & MIH_C_BIT_LINK_ACTION)) { - *status = MIH_C_STATUS_REJECTED; - return 1; - } - - *status = MIH_C_STATUS_SUCCESS; - - /* Check whether the action request is supported */ - if (ralpriv->mih_supported_link_action_list & (1 << action)) { - /* Check whether another action request is currently in progress */ - if ((ralpriv->pending_req_action) && (ralpriv->pending_req_action != action)) { - /* Another action request is in progress: - * Do not process new request before completion of this one */ - *ac_status = MIH_C_LINK_AC_RESULT_REFUSED; - return 1; - } - - /* The action request is supported and no other request is in progress: - * Go ahead and process the request */ - return 0; - } - - /* The link action request is not supported */ - *ac_status = MIH_C_LINK_AC_RESULT_INCAPABLE; - return 1; -} - -#ifdef MIH_C_MEDIEVAL_EXTENSIONS -/**************************************************************************** - ** ** - ** Name: _eRALlte_action_link_flow_attr() ** - ** ** - ** Description: Processes the link flow attribut action request. ** - ** ** - ** Inputs: None ** - ** Others: g_link_action ** - ** ** - ** Outputs: None ** - ** Return: MIH_C_LINK_AC_RESULT_SUCCESS if action has ** - ** been successfully processed. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -static MIH_C_LINK_AC_RESULT_T _eRALlte_action_link_flow_attr(void) -//TODO -{ - MIH_C_FLOW_ATTRIBUTE_T *flow = &g_link_action.link_ac_param._union.flow_attribute; - int mt_ix, ch_ix, f_ix; - int cnxid; - - /* Get the connection identifier */ - f_ix = _eRALlte_action_get_channel_id(&flow->flow_id, &cnxid); - - if (f_ix < 0) { - DEBUG(" No RB allocated for this data flow\n"); - return MIH_C_LINK_AC_RESULT_REFUSED; - } - - /* Get MT and RB channel identifiers */ - if (eRALlte_process_find_channel(cnxid, &mt_ix, &ch_ix) != 0) { - /* Unicast data flow */ - DEBUG (" %s: Unicast MT's address = %s\n", __FUNCTION__, - eRALlte_process_mt_addr_to_string(ralpriv->mt[mt_ix].ipv6_addr)); - } else { - /* Multicast data flow */ - DEBUG (" %s: Multicast MT's address = %s\n", __FUNCTION__, - eRALlte_process_mt_addr_to_string(ralpriv->mcast.mc_group_addr)); - } - - if (flow->choice_mark_qos) { - DEBUG(" Mark QoS enabled\n"); - //TODO ??? - } - - if (flow->choice_mark_drop_eligibility) { - DEBUG(" Mark drop eligibility enabled\n"); - //TODO ??? - } - - /* Link action successfully processed */ - ralpriv->pending_req_action = MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR; - return MIH_C_LINK_AC_RESULT_SUCCESS; -} - -/**************************************************************************** - ** ** - ** Name: _eRALlte_action_link_activate_resources() ** - ** ** - ** Description: Processes the link activate resource action request. ** - ** ** - ** Inputs: None ** - ** Others: g_link_action ** - ** ** - ** Outputs: None ** - ** Return: MIH_C_LINK_AC_RESULT_SUCCESS if action has ** - ** been successfully processed. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -static MIH_C_LINK_AC_RESULT_T _eRALlte_action_link_activate_resources(void) -{ - MIH_C_RESOURCE_DESC_T *res = &g_link_action.link_ac_param._union.resource_desc; - MIH_C_COS_T classIdDL = 0; - MIH_C_COS_T classIdUL = 0; - MIH_C_LINK_DATA_RATE_T resBitrateDL = 0; - MIH_C_LINK_DATA_RATE_T resBitrateUL = 0; - MIH_C_BOOLEAN_T multicast = MIH_C_BOOLEAN_FALSE; - - /* TODO: To be initialized downlink/uplink */ - if (res->choice_qos) { - MIH_C_QOS_T *qos = &(res->_union_qos.qos); - - if (qos->choice) { - classIdDL = qos->_union.cos; - classIdUL = qos->_union.cos; - } - } - - if (res->choice_link_data_rate) { - resBitrateDL = res->_union_link_data_rate.link_data_rate; - resBitrateUL = res->_union_link_data_rate.link_data_rate; - } - - /* end TODO */ - - if (res->choice_multicast_enable) { - multicast = res->_union_multicast_enable.multicast_enable; - } - - /* - * Get the Care-of Address (MT address): - * The destination address is contained into the MIH_C_FLOW_ID structure - * within the MIH_C_RESOURCE_DESC parameters of the request. - */ - char mt_addr[128]; - //original code: int len = MIH_C_TRANSPORT_ADDR_VALUE2String(&res->flow_id.dest_addr.ip_addr.address, mt_addr); - - MIH_C_TRANSPORT_ADDR_VALUE_T mihc_transport_addr_value; - MIH_C_TRANSPORT_ADDR_VALUE_set(&mihc_transport_addr_value, (unsigned char*)"2001:660:382:14:335:600:8014:9150", strlen("2001:660:382:14:335:600:8014:9150")); - - int len = MIH_C_TRANSPORT_ADDR_VALUE2String(&mihc_transport_addr_value, mt_addr); - //int len = MIH_C_TRANSPORT_ADDR_VALUE2String(&DestIpv6Addr[0][16], mt_addr); - - if ( (len > 0) && (len < 128)) { - DEBUG (" %s: MT's address = %s\n", __FUNCTION__, eRALlte_process_mt_addr_to_string((unsigned char*)mt_addr)); - } else { - ERR (" %s : IP Address is NOT valid (len=%d)\n", __FUNCTION__, len); - return MIH_C_LINK_AC_RESULT_FAILURE; - } - -#if 0 - char mt_addr[128]; - - if (res->link_id.link_addr.choice == MIH_C_CHOICE_3GPP_3G_CELL_ID) { - char link_addr[128]; - int len = MIH_C_LINK_ADDR2String(&res->link_id.link_addr, link_addr); - - if ( (len > 0) && (len <= 128) ) { - int i; - DEBUG (" %s : Link address = %s\n", __FUNCTION__, link_addr); - - for (i=0; i < len; i++) { - if (link_addr[i] == '=') break; - } - - strncpy(mt_addr, &link_addr[i+2], 16); - DEBUG (" %s : MT address = %s\n", __FUNCTION__, mt_addr); - } else { - ERR (" %s : Link address is NOT valid (len=%d)\n", __FUNCTION__, len); - return MIH_C_LINK_AC_RESULT_FAILURE; - } - } else { - ERR (" %s : Link address is NOT valid (type=%d, not 3GPP_3G_CELL_ID)\n", - __FUNCTION__, res->link_id.link_addr.choice); - return MIH_C_LINK_AC_RESULT_FAILURE; - } - -#endif - - /* - * If the resource has already been activated, check whether it is in the - * required state. - */ - struct ral_lte_channel *currChannel; - int mt_ix, ch_ix, f_ix; - int cnxid; - - /* Get the connection identifier */ - f_ix = _eRALlte_action_get_channel_id(&res->flow_id, &cnxid); - - if (f_ix != -1) { - /* Get MT and RB channel identifiers */ - if (eRALlte_process_find_channel(cnxid, &mt_ix, &ch_ix) != 0) { - /* Unicast data flow */ - currChannel = &(ralpriv->mt[mt_ix].radio_channel[ch_ix]); - } else { - /* Multicast data flow */ - assert(multicast == MIH_C_BOOLEAN_TRUE); - currChannel = &(ralpriv->mcast.radio_channel); - } - - if (currChannel->status == NAS_CONNECTED) { - /* The resource is already in the required state */ - DEBUG(" Link action ACTIVATE_RESOURCES requested while link resource is ALREADY activated\n"); - return MIH_C_LINK_AC_RESULT_SUCCESS; - } - - /* The resource is not in the required state: - * Remove the connection identifier from the list of active resources - * and process the action request again. */ - DEBUG(" Resource has been activated but is not in the ACTIVE state\n"); - (void) _eRALlte_action_del_channel_id(f_ix); - } - - MIH_C_LINK_TUPLE_ID_T *ltid; - int is_ready_for_rb_establish = 1; - - if (multicast) { - /* - * Multicast data flow: - */ - mt_ix = RAL_MAX_MT; - ch_ix = 0; - currChannel = &(ralpriv->mcast.radio_channel); - currChannel->cnx_id = (RAL_MAX_RB_PER_UE*mt_ix)+1; - currChannel->rbId = RAL_DEFAULT_RAB_ID; - currChannel->multicast = 1; - memcpy((char*)&(ralpriv->mcast.mc_group_addr), mt_addr, 16); - ltid = &(ralpriv->mcast.ltid); - } else { - /* - * Unicast data flow - */ - /* Get the list of MTs waiting for RB establishment */ -#ifdef RAL_REALTIME - TQAL_process_NAS_message(IO_OBJ_CNX, IO_CMD_LIST, 0, 0); - TQAL_process_NAS_message(IO_OBJ_RB, IO_CMD_LIST, 0, 0); -#endif - /* Check if the MT is in the list */ - mt_ix = eRALlte_process_find_mt_by_addr(mt_addr); - - if ( (mt_ix < RAL_MAX_MT) && - (ralpriv->mt[mt_ix].mt_state == RB_CONNECTED)) { - /* The MT is ready for RB establishment */ - ch_ix = eRALlte_process_find_new_channel(mt_ix); - - if (ch_ix == RAL_MAX_RB) { - DEBUG(" No RB available in MT\n"); - return MIH_C_LINK_AC_RESULT_REFUSED; - } - - currChannel = &(ralpriv->mt[mt_ix].radio_channel[ch_ix]); - currChannel->cnx_id = (RAL_MAX_RB_PER_UE*mt_ix)+ch_ix+1; - currChannel->rbId = RAL_DEFAULT_RAB_ID + ch_ix; - currChannel->multicast = 0; - DEBUG(" mt_ix %d, ch_ix %d, cnx_id %d, rbId %d\n", - mt_ix, ch_ix, currChannel->cnx_id, currChannel->rbId); - memcpy((char *)&(ralpriv->mt[mt_ix].ipv6_addr), mt_addr, 16); - ltid = &(ralpriv->mt[mt_ix].ltid); - } else { - /* The MT is NOT ready for RB establishment */ - is_ready_for_rb_establish = 0; - int qos_is_valid = 0; - - DEBUG(" Mobile Terminal not ready - Storing request data\n"); - - /* Check validity of QoS parameters */ - if ( (classIdDL < 64) && (classIdUL < 64) ) { - if ( (resBitrateDL <= RAL_BITRATE_320k) - && (resBitrateUL <= RAL_BITRATE_320k) ) { - qos_is_valid = 1; - } else if ( (resBitrateDL >= RAL_BITRATE_384k) - && (resBitrateDL <= RAL_BITRATE_440k) - && (resBitrateUL <= RAL_BITRATE_64k) ) { - qos_is_valid = 1; - } - } - - if (qos_is_valid) { - DEBUG(" Received QoS parameters are valid\n"); - } else { - DEBUG(" Received QoS parameters are NOT valid - Request will be rejected\n"); - return MIH_C_LINK_AC_RESULT_REFUSED; - } - - currChannel = &(ralpriv->pending_mt.radio_channel[0]); - currChannel->cnx_id = 0; - currChannel->rbId = 0; - currChannel->multicast = 0; - memcpy((char *)&(ralpriv->pending_mt.ipv6_addr), mt_addr, 16); - - ltid = &(ralpriv->pending_mt.ltid); - ralpriv->pending_req_flag = 1; - - } /* end MT not ready */ - - } /* end unicast data flow */ - - /* Save the current data flow identifier into the list of active data flows */ - if (currChannel->cnx_id != 0) { - f_ix = _eRALlte_action_set_channel_id(&res->flow_id, currChannel->cnx_id); - - if (f_ix < 0) { - DEBUG(" No RB available\n"); - return MIH_C_LINK_AC_RESULT_REFUSED; - } - } else { - /* The current request is pending waiting for RB establishment */ - f_ix = 0; - ralpriv->pending_req_fid = res->flow_id; - } - - /* - * Store resource parameters - */ - int i; - - for (i = 0; i < 2; i++) { - //TODO: int dir = p->qos.value[i].direction; - // TODO: To be initialized downlink/uplink - currChannel->flowId[i] = f_ix; - currChannel->classId[i] = classIdDL; // classIdUL - currChannel->resBitrate[i] = resBitrateDL; // resBitrateUL - //currChannel->meanBitrate[i] = p->qos.value[i].tspec.meanBitrate; - //currChannel->bktDepth[i] = p->qos.value[i].tspec.bucketDepth; - //currChannel->pkBitrate[i] = p->qos.value[i].tspec.peakBitrate; - //currChannel->MTU[i] = p->qos.value[i].tspec.maximumTransmissionUnit; - DEBUG(" qos value : DIR %d, flowId %d, classId %d, resBitrate %.1f\n", i , currChannel->flowId[i], currChannel->classId[i], currChannel->resBitrate[i]); - } - - /* Store the link identifier */ - ltid->link_id = res->link_id; - ltid->choice = MIH_C_LINK_TUPLE_ID_CHOICE_LINK_ADDR; - ltid->_union.link_addr.choice = MIH_C_CHOICE_3GPP_3G_CELL_ID; // DUMMY - ltid->_union.link_addr._union._3gpp_3g_cell_id.cell_id = RAL_DEFAULT_CELL_ID; // DUMMY - - /* - * Setup Radio Bearer resources - */ - if (is_ready_for_rb_establish) { - /* Map QoS */ - int mapping_result = eRALlte_process_map_qos(mt_ix, ch_ix); - - if (mapping_result) { - int rc; -#ifdef RAL_DUMMY - rc = eRALlte_NAS_send_rb_establish_request(mt_ix, ch_ix); -#endif -#ifdef RAL_REALTIME - rc = TQAL_process_NAS_message(IO_OBJ_RB, IO_CMD_ADD, mt_ix, ch_ix); -#endif - - if (rc < 0) { - /* Failed to send RB establishment request */ - return MIH_C_LINK_AC_RESULT_FAILURE; - } - } else { - /* QoS mapping is not supported */ - return MIH_C_LINK_AC_RESULT_REFUSED; - } - } else { - /* Wait for MT coming ready; - * re-try to establish RB upon timer expiration */ -#ifdef RAL_DUMMY - ralpriv->pending_mt_timer = 5; -#endif -#ifdef RAL_REALTIME - ralpriv->pending_mt_timer = 300; -#endif - } - - /* Link action successfully processed */ - ralpriv->pending_req_action = MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES; - return MIH_C_LINK_AC_RESULT_SUCCESS; -} - -/**************************************************************************** - ** ** - ** Name: _eRALlte_action_link_deactivate_resources() ** - ** ** - ** Description: Processes the link deactivate resource action request. ** - ** ** - ** Inputs: None ** - ** Others: g_link_action ** - ** ** - ** Outputs: None ** - ** Return: MIH_C_LINK_AC_RESULT_SUCCESS if action has ** - ** been successfully processed. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -static MIH_C_LINK_AC_RESULT_T _eRALlte_action_link_deactivate_resources(void) -{ - MIH_C_RESOURCE_DESC_T *res = &g_link_action.link_ac_param._union.resource_desc; - struct ral_lte_channel *currChannel; - int mt_ix, ch_ix, f_ix; - int cnxid; - - /* Get the connection identifier */ - f_ix = _eRALlte_action_get_channel_id(&res->flow_id, &cnxid); - - if (f_ix < 0) { - DEBUG(" Link action DEACTIVATE_RESOURCES requested while link resource is NOT activated\n"); - return MIH_C_LINK_AC_RESULT_SUCCESS; - } - - /* Get MT and RB channel identifiers */ - if (eRALlte_process_find_channel(cnxid, &mt_ix, &ch_ix) != 0) { - /* Unicast data flow */ - currChannel = &(ralpriv->mt[mt_ix].radio_channel[ch_ix]); - DEBUG (" %s: Unicast MT's address = %s\n", __FUNCTION__, - eRALlte_process_mt_addr_to_string(ralpriv->mt[mt_ix].ipv6_addr)); - } else { - /* Multicast data flow */ - currChannel = &(ralpriv->mcast.radio_channel); - DEBUG (" %s: Multicast MT's address = %s\n", __FUNCTION__, - eRALlte_process_mt_addr_to_string(ralpriv->mcast.mc_group_addr)); - } - - if (currChannel->status == NAS_DISCONNECTED) { - /* The resource is already in the required state */ - DEBUG(" Link action request DEACTIVATE_RESOURCES is currently in progress\n"); - return MIH_C_LINK_AC_RESULT_SUCCESS; - } - - /* The resource is not in the required state: - * Remove the connection identifier from the list of active resources - * and go ahead in the request processing. */ - (void) _eRALlte_action_del_channel_id(f_ix); - - int rc; -#ifdef RAL_DUMMY - rc = eRALlte_NAS_send_rb_release_request(mt_ix, ch_ix); -#endif -#ifdef RAL_REALTIME - rc = TQAL_process_NAS_message(IO_OBJ_RB, IO_CMD_DEL, mt_ix, ch_ix); -#endif - - if (rc < 0) { - /* Failed to send RB release request */ - return MIH_C_LINK_AC_RESULT_FAILURE; - } - - /* Link action successfully processed */ - ralpriv->pending_req_action = MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES; - return MIH_C_LINK_AC_RESULT_SUCCESS; -} - -#endif // MIH_C_MEDIEVAL_EXTENSIONS diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_main.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_main.c deleted file mode 100644 index 7663afa49e..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_main.c +++ /dev/null @@ -1,532 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include <sys/select.h> -#include <getopt.h> - -#define DEFINE_GLOBAL_CONSTANTS -#include "eRALlte_constants.h" -#include "eRALlte_variables.h" -#include "eRALlte_proto.h" -#include "eRALlte_mih_msg.h" - -#include "MIH_C.h" - -/****************************************************************************/ -/******************* G L O C A L D E F I N I T I O N S *****************/ -/****************************************************************************/ - -/* NAS socket file descritor */ -int g_sockd_nas; // referenced in eRALlte_NAS.c - -/* RAL LTE internal data */ -struct ral_lte_priv *ralpriv; - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -static int g_log_output; -static struct ral_lte_priv rl_priv; - -static void arg_usage(const char* name); -static int parse_opts(int argc, char* argv[]); -static void NAS_Netlink_socket_init(void); -static void get_IPv6_addr(const char* if_name); - -static int RAL_initialize(int argc, const char *argv[]); - -static int netl_s; /* NAS net link socket */ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -int main(int argc, const char *argv[]) -{ - int rc, done; - fd_set readfds; - struct timeval tv; - - RAL_initialize(argc, argv); - - ralpriv->pending_mt_timer = 0; - - done = 0; - - do { - /* Initialize fd_set and wait for input */ - FD_ZERO(&readfds); - FD_SET(g_sockd_mihf, &readfds); - FD_SET(g_sockd_nas, &readfds); - tv.tv_sec = MIH_C_RADIO_POLLING_INTERVAL_SECONDS; - tv.tv_usec = MIH_C_RADIO_POLLING_INTERVAL_MICRO_SECONDS; - - rc = select(FD_SETSIZE, &readfds, NULL, NULL, &tv); - - if (rc < 0) { - perror("main : select() failed"); - done = 1; - } - - /* Something is ready for being read */ - else if (rc >= 0) { - /* Read data coming from the MIH Function */ - if (FD_ISSET(g_sockd_mihf, &readfds)) { - done = eRALlte_mih_link_process_message(); - } - - /* Read data coming from the NAS driver */ - if (FD_ISSET(g_sockd_nas, &readfds)) { - done = eRALlte_NAS_process_message(); - } - - /* Wait until next pending MT's timer expiration */ - if (ralpriv->pending_mt_timer > 0) { - ralpriv->pending_mt_timer --; - eRALlte_process_verify_pending_mt_status(); - } - } - } while (!done); - - free(g_ral_ip_address); - free(g_ral_listening_port_for_mihf); - free(g_mihf_remote_port); - free(g_mihf_ip_address); - free(g_link_id); - free(g_mihf_id); - - close(g_sockd_mihf); - close(netl_s); - MIH_C_exit(); - return 0; -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: arg_usage() ** - ** ** - ** Description: Displays command line usage ** - ** ** - ** Inputs: name: Name of the running process ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -static void arg_usage(const char *name) -{ - fprintf(stderr, - "Usage: %s [options]\nOptions:\n" - " -V, --version Display version information\n" - " -?, -h, --help Display this help text\n" - " -P <number>, --ral-listening-port Listening port for incoming MIH-F messages\n" - " -I <string>, --ral-ip-address Binding IP(v4 or v6) address for RAL\n" - " -p <number>, --mihf-remote-port MIH-F remote port\n" - " -i <string>, --mihf-ip-address MIH-F IP(v4 or v6) address\n" - " -l <number>, --mihf-link-id MIH-F link identifier\n" - " -m <number>, --mihf-id MIH-F identifier\n" - " -c, --output-to-console All stream outputs are redirected to console\n" - " -f, --output-to-file All stream outputs are redirected to file\n" - " -s, --output-to-syslog All stream outputs are redirected to syslog\n", - name); -} - -/**************************************************************************** - ** ** - ** Name: parse_opts() ** - ** ** - ** Description: Parses the command line parameters ** - ** ** - ** Inputs: argc: Number of parameters in the command line ** - ** argv: Command line parameters ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -static int parse_opts(int argc, char *argv[]) -{ - static struct option long_opts[] = { - {"version", 0, 0, 'V'}, - {"help", 0, 0, 'h'}, - {"help", 0, 0, '?'}, - {"ral-listening-port", optional_argument, 0, 'P'}, - {"ral-ip-address", optional_argument, 0, 'I'}, - {"mihf-remote-port", optional_argument, 0, 'p'}, - {"mihf-ip-address", optional_argument, 0, 'i'}, - {"mihf-link-id", optional_argument, 0, 'l'}, - {"mihf-id", optional_argument, 0, 'm'}, - {"output-to-console", 0, 0, 'c'}, - {"output-to-file", 0, 0, 'f'}, - {"output-to-syslog", 0, 0, 's'}, - {0, 0, 0, 0} - }; - - /* parse all other cmd line parameters than -c */ - while (1) { - int idx, c; - c = getopt_long(argc, argv, "P:I:p:i:l:m:Vh?cfs", long_opts, &idx); - - if (c == -1) break; - - switch (c) { - case 'V': - fprintf(stderr, "SVN MODULE VERSION: %s\n", SVN_REV); - return -1; - - case '?': - case 'h': - arg_usage(basename(argv[0])); - return -1; - - case 'i': - strncpy(g_mihf_ip_address, optarg, strlen(g_mihf_ip_address)); - break; - - case 'p': - strncpy(g_mihf_remote_port, optarg, strlen(g_mihf_remote_port)); - break; - - case 'P': - strncpy(g_ral_listening_port_for_mihf, optarg, - strlen(g_ral_listening_port_for_mihf)); - break; - - case 'I': - strncpy(g_ral_ip_address, optarg, strlen(g_ral_ip_address)); - break; - - case 'l': - strncpy(g_link_id, optarg, strlen(g_link_id)); - break; - - case 'm': - strncpy(g_mihf_id, optarg, strlen(g_mihf_id)); - break; - - case 'c': - g_log_output = LOG_TO_CONSOLE; - break; - - case 'f': - g_log_output = LOG_TO_FILE; - break; - - case 's': - g_log_output = LOG_TO_SYSTEM; - break; - - default: - break; - }; - } - - return 0; -} - -/**************************************************************************** - ** ** - ** Name: NAS_Netlink_socket_init() ** - ** ** - ** Description: Initializes the communication channel with the NAS driver ** - ** ** - ** Inputs: None ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: netl_s : the NAS net link socket ** - ** ** - ***************************************************************************/ -static void NAS_Netlink_socket_init(void) -{ - int len; - struct sockaddr_un local; - - if ((netl_s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - perror("NAS_Netlink_socket_init : socket() failed"); - exit(1); - } - - local.sun_family = AF_UNIX; - strcpy(local.sun_path, SOCK_TQAL_NAS_PATH); - unlink(local.sun_path); - len = strlen(local.sun_path) + sizeof(local.sun_family); - - if (bind(netl_s, (struct sockaddr *)&local, len) == -1) { - perror("NAS_Netlink_socket_init : bind() failed"); - exit(1); - } - - if (listen(netl_s, 1) == -1) { - perror("NAS_Netlink_socket_init : listen() failed"); - exit(1); - } -} - -/**************************************************************************** - ** ** - ** Name: get_IPv6_addr() ** - ** ** - ** Description: Gets the IPv6 address of the specified network interface. ** - ** ** - ** Inputs: if_name Interface name ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -static void get_IPv6_addr(const char* if_name) -{ -#define IPV6_ADDR_LINKLOCAL 0x0020U - - FILE *f; - char devname[20]; - int plen, scope, dad_status, if_idx; - char addr6p[8][5]; - int found = 0; - char my_addr[16]; - char temp_addr[32]; - int i, j; - - DEBUG(" %s : network interface %s\n", __FUNCTION__, if_name); - - if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) { - while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], - addr6p[4], addr6p[5], addr6p[6], addr6p[7], - &if_idx, &plen, &scope, &dad_status, devname) != EOF) { - - if (!strcmp(devname, if_name)) { - found = 1; - - // retrieve numerical value - if ((scope == 0) || (scope == IPV6_ADDR_LINKLOCAL)) { - DEBUG(" adresse %s:%s:%s:%s:%s:%s:%s:%s", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], - addr6p[4], addr6p[5], addr6p[6], addr6p[7]); - DEBUG(" Scope:"); - - switch (scope) { - case 0: - DEBUG(" Global\n"); - break; - - case IPV6_ADDR_LINKLOCAL: - DEBUG(" Link\n"); - break; - - default: - DEBUG(" Unknown\n"); - break; - } - - DEBUG(" Numerical value: "); - - for (i = 0; i < 8; i++) { - for (j = 0; j < 4; j++) { - addr6p[i][j]= toupper(addr6p[i][j]); - - if ((addr6p[i][j] >= 'A') && (addr6p[i][j] <= 'F')) { - temp_addr[(4*i)+j] =(unsigned short int)(addr6p[i][j]-'A')+10; - } else if ((addr6p[i][j] >= '0') && (addr6p[i][j] <= '9')) { - temp_addr[(4*i)+j] =(unsigned short int)(addr6p[i][j]-'0'); - } - } - - my_addr[2*i] = (16*temp_addr[(4*i)])+temp_addr[(4*i)+1]; - my_addr[(2*i)+1] = (16*temp_addr[(4*i)+2])+temp_addr[(4*i)+3]; - - } - - for (i = 0; i < 16; i++) { - DEBUG("-%hhx-",my_addr[i]); - } - - DEBUG("\n"); - } - } - } - - fclose(f); - - if (!found) { - ERR(" %s : interface %s not found\n\n", __FUNCTION__, if_name); - } - } -} - -/**************************************************************************** - ** ** - ** Name: RAL_initialize() ** - ** ** - ** Description: Performs overall RAL LTE initialisations: ** - ** - Default value of global variables ** - ** - Command line parsing ** - ** - List of supported MIH actions ** - ** - List of supported MIH link-events ** - ** - Communication channel with the NAS driver ** - ** - MIH link registration ** - ** ** - ** Inputs: argc: Number of parameters in the command line ** - ** argv: Command line parameters ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_mihf_ip_address, g_mihf_remote_port ** - ** g_sockd_mihf, g_ral_ip_address, ** - ** g_ral_listening_port_for_mihf ** - ** g_link_id, g_mihf_id, g_log_output ** - ** g_sockd_nas, ralpriv ** - ** ** - ***************************************************************************/ -static int RAL_initialize(int argc, const char *argv[]) -{ - MIH_C_TRANSACTION_ID_T transaction_id; - unsigned int t; - struct sockaddr_un nas_socket; - - ralpriv = &rl_priv; - memset(ralpriv, 0, sizeof(struct ral_lte_priv)); - - /* - * Initialize defaults - */ - g_ral_ip_address = strdup(DEFAULT_IP_ADDRESS_RAL); - g_ral_listening_port_for_mihf = strdup(DEFAULT_LOCAL_PORT_RAL); - g_mihf_remote_port = strdup(DEFAULT_REMOTE_PORT_MIHF); - g_mihf_ip_address = strdup(DEFAULT_IP_ADDRESS_MIHF); - g_sockd_mihf = -1; - g_link_id = strdup(DEFAULT_LINK_ID); - g_mihf_id = strdup(DEFAULT_MIHF_ID); - g_log_output = LOG_TO_CONSOLE; - - /* - * Parse command line parameters - */ - if (parse_opts(argc, (char**) argv) < 0) { - exit(0); - } - - MIH_C_init(g_log_output); - - DEBUG(" %s -I %s -P %s -i %s -p %s -l %s -m %s\n", argv[0], - g_ral_ip_address, g_ral_listening_port_for_mihf, - g_mihf_ip_address, g_mihf_remote_port, - g_link_id, g_mihf_id); - - /* - * Connect to the MIF Function - */ - DEBUG(" Connect to the MIH-F ...\n"); - - if (eRALlte_mihf_connect() < 0 ) { - ERR(" %s : Could not connect to MIH-F...exiting\n", __FUNCTION__); - exit(-1); - } - - // excluded MIH_C_LINK_AC_TYPE_NONE - // excluded MIH_C_LINK_AC_TYPE_LINK_DISCONNECT - // excluded MIH_C_LINK_AC_TYPE_LINK_LOW_POWER - // excluded MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN - // excluded MIH_C_LINK_AC_TYPE_LINK_POWER_UP - ralpriv->mih_supported_link_action_list = - (1 << MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR) | - (1 << MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES) | - (1 << MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES); - - // excluded MIH_C_BIT_LINK_DETECTED - // excluded MIH_C_BIT_LINK_PARAMETERS_REPORT - // excluded MIH_C_BIT_LINK_GOING_DOWN - // excluded MIH_C_BIT_LINK_HANDOVER_IMMINENT - // excluded MIH_C_BIT_LINK_HANDOVER_COMPLETE - // excluded MIH_C_BIT_LINK_PDU_TRANSMIT_STATUS - ralpriv->mih_supported_link_event_list = - MIH_C_BIT_LINK_UP | - MIH_C_BIT_LINK_DOWN; - - // excluded MIH_C_BIT_LINK_GET_PARAMETERS - // excluded MIH_C_BIT_LINK_CONFIGURE_THRESHOLDS - ralpriv->mih_supported_link_command_list = - MIH_C_BIT_LINK_EVENT_SUBSCRIBE | - MIH_C_BIT_LINK_EVENT_UNSUBSCRIBE | - MIH_C_BIT_LINK_ACTION; - - NOTICE("[MSC_NEW][%s][MIH-F=%s]\n", getTimeStamp4Log(), g_mihf_id); - NOTICE("[MSC_NEW][%s][RAL=%s]\n", getTimeStamp4Log(), g_link_id); - NOTICE("[MSC_NEW][%s][NAS=%s]\n", getTimeStamp4Log(), "nas"); - - /* - * Initialize the NAS driver communication channel - */ - NAS_Netlink_socket_init(); - DEBUG(" Waiting for a connection from the NAS Driver ...\n"); - t = sizeof(nas_socket); - - if ((g_sockd_nas = accept(netl_s, (struct sockaddr *)&nas_socket, &t)) == -1) { - perror("RAL_initialize : g_sockd_nas - accept() failed"); - exit(1); - } - - DEBUG(" NAS Driver Connected.\n\n"); - - /* - * Get the interface IPv6 address - */ -#ifdef RAL_DUMMY - get_IPv6_addr("eth0"); -#else -#ifdef RAL_REALTIME - get_IPv6_addr("graal0"); -#endif -#endif - - /* - * Get the list of MTs - */ - eRALlte_NAS_get_MTs_list(); - DEBUG(" List of MTs initialized\n\n"); - - transaction_id = (MIH_C_TRANSACTION_ID_T)0; - eRALlte_send_link_register_indication(&transaction_id); - - return 0; -} diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_mih_msg.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_mih_msg.c deleted file mode 100644 index 92dfd626bd..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_mih_msg.c +++ /dev/null @@ -1,1945 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include "eRALlte_mih_msg.h" - -#include "eRALlte_constants.h" -#include "eRALlte_variables.h" - -#include "eRALlte_subscribe.h" -#include "eRALlte_parameters.h" -#include "eRALlte_thresholds.h" -#include "eRALlte_action.h" - -/****************************************************************************/ -/******************* G L O C A L D E F I N I T I O N S *****************/ -/****************************************************************************/ - -#define MSG_CODEC_RECV_BUFFER_SIZE 16400 -#define MSG_CODEC_SEND_BUFFER_SIZE 16400 - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -static u_int8_t g_msg_codec_recv_buffer[MSG_CODEC_RECV_BUFFER_SIZE] = {}; -static u_int8_t g_msg_codec_send_buffer[MSG_CODEC_SEND_BUFFER_SIZE] = {}; - -static char g_msg_print_buffer[8192] = {}; -static char g_msg_codec_print_buffer[8192] = {}; - -static int eRALlte_mih_link_msg_decode(Bit_Buffer_t* bbP, MIH_C_Message_Wrapper_t *message_wrapperP); - -static int eRALlte_send_to_mih(const u_int8_t *bufferP, int lenP); - -static void eRALlte_print_buffer(const u_int8_t * bufferP, int lenP); - -#ifdef MSCGEN_PYTOOL -#define MSC_GEN_BUF_SIZE 1024 -static char g_msc_gen_buf[MSC_GEN_BUF_SIZE]; -static unsigned int g_msc_gen_buffer_index; -#endif - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/* - * ------------------------------------------------------------------------- - * Functions used to send MIH link service management messages - * ------------------------------------------------------------------------- - */ - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_link_register_indication() ** - ** ** - ** Description: Sends a Link_Register.indication message to the MIHF. ** - ** ** - ** This message is ODTONE specific and not defined by the ** - ** 802.21 standard. It allows the Link SAP to send informa- ** - ** tions to the MIHF about which technology it supports and ** - ** which interface it manages. ** - ** Upon receiving this message the MIHF executes its Link ** - ** SAPs discovery procedure in order to get the full link ** - ** capabilities. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** Others: g_link_id, g_mihf_id, ralpriv ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_link_register_indication(MIH_C_TRANSACTION_ID_T *tidP) -{ - MIH_C_Message_Link_Register_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; - - DEBUG(" Send MIH_C_MESSAGE_LINK_REGISTER_INDICATION\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Register_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)6; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Link_Id.link_type = MIH_C_WIRELESS_UMTS; - message.primitive.Link_Id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_3G_CELL_ID; - - Bit_Buffer_t *plmn = new_BitBuffer_0(); - BitBuffer_wrap(plmn, (unsigned char*) ralpriv->plmn, DEFAULT_PLMN_SIZE); - MIH_C_PLMN_ID_decode(plmn, &message.primitive.Link_Id.link_addr._union._3gpp_3g_cell_id.plmn_id); - message.primitive.Link_Id.link_addr._union._3gpp_3g_cell_id.cell_id = ralpriv->curr_cellId; - free_BitBuffer(plmn); - - message_total_length = MIH_C_Link_Message_Encode_Link_Register_indication(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - MIH_C_LINK_ID2String(&message.primitive.Link_Id, g_msc_gen_buf); -#endif - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Register.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Register.indication\\n%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Register.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Register.indication\\n%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_capability_discover_confirm() ** - ** ** - ** Description: Sends capability discover service management response to ** - ** the MIH-F. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** statusP: Status of operation ** - ** levt_listP: List of events supported by the link layer ** - ** lcmd_listP: List of commands supported by the link ** - ** layer ** - ** Others: g_link_id, g_mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_capability_discover_confirm(MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *link_evt_listP, - MIH_C_LINK_CMD_LIST_T *link_cmd_listP) -{ - MIH_C_Message_Link_Capability_Discover_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; - - DEBUG(" Send MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_CONFIRM\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Capability_Discover_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.SupportedLinkEventList = link_evt_listP; - message.primitive.SupportedLinkCommandList = link_cmd_listP; - - message_total_length = MIH_C_Link_Message_Encode_Capability_Discover_confirm(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n\\nsupported link events="); - g_msc_gen_buffer_index += MIH_C_LINK_EVENT_LIST2String2(message.primitive.SupportedLinkEventList, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nsupported commands="); - g_msc_gen_buffer_index += MIH_C_LINK_CMD_LIST2String2(message.primitive.SupportedLinkCommandList, &g_msc_gen_buf[g_msc_gen_buffer_index]); -#endif - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Capability_Discover.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Capability_Discover.confirm\\nstatus=%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Capability_Discover.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Capability_Discover.confirm\\nstatus=%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_event_subscribe_confirm() ** - ** ** - ** Description: Sends a Link_Event_Subscribe.confirm message to the MIHF. ** - ** ** - ** This primitive is generated in response to a Link_Event_ ** - ** Subscribe.request. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** statusP: Status of operation ** - ** levt_listP: List of successfully subscribed link events** - ** Others: g_link_id, g_mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_event_subscribe_confirm(MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *levt_listP) -{ - MIH_C_Message_Link_Event_Subscribe_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; - - DEBUG(" Send MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_CONFIRM\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Event_Subscribe_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)4; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.ResponseLinkEventList = levt_listP; - - message_total_length = MIH_C_Link_Message_Encode_Event_Subscribe_confirm(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - - if (levt_listP) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nlink event list="); - g_msc_gen_buffer_index += MIH_C_LINK_EVENT_LIST2String2(message.primitive.ResponseLinkEventList, &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - -#endif - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Event_Subscribe.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Subscribe.confirm\\nstatus=%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Event_Subscribe.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Subscribe.confirm\\nstatus=%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_event_unsubscribe_confirm() ** - ** ** - ** Description: Sends a Link_Event_Unsubscribe.confirm message to the ** - ** MIHF. ** - ** ** - ** This primitive is generated in response to a Link_Event_ ** - ** Unsubscribe.request. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** statusP: Status of operation ** - ** levt_listP: List of successfully subscribed link events** - ** Others: g_link_id, g_mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_event_unsubscribe_confirm(MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *levt_listP) -{ - MIH_C_Message_Link_Event_Unsubscribe_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; - - DEBUG(" Send MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_CONFIRM\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Event_Unsubscribe_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)5; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.ResponseLinkEventList = levt_listP; - - message_total_length = MIH_C_Link_Message_Encode_Event_Unsubscribe_confirm(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - - if (levt_listP) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nlink event list="); - g_msc_gen_buffer_index += MIH_C_LINK_EVENT_LIST2String2(message.primitive.ResponseLinkEventList, &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - -#endif - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Event_Unsubscribe.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Unsubscribe.confirm\\nstatus=%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Event_Unsubscribe.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Unsubscribe.confirm\\nstatus=%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/* - * ------------------------------------------------------------------------- - * Functions used to send MIH link event messages - * ------------------------------------------------------------------------- - */ - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_link_detected_indication() ** - ** ** - ** Description: Sends a Link_Detected.indication message to the MIHF. ** - ** ** - ** The Link Detected event is generated on the MN when the ** - ** first PoA of an access network is detected. This event is ** - ** not generated when subsequent PoAs of the same access ** - ** network are discovered during the active connection on ** - ** that link. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** linfoP: Information of the detected link ** - ** Others: g_link_id, g_mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_link_detected_indication(MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_LINK_DET_INFO_T *linfoP) -{ - MIH_C_Message_Link_Detected_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; - - if (!(ralpriv->mih_supported_link_event_list & MIH_C_BIT_LINK_DETECTED)) { - return; - } - - DEBUG(" Send MIH_C_MESSAGE_LINK_DETECTED_INDICATION\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Detected_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - memcpy(&message.primitive.LinkDetectedInfo, linfoP, - sizeof(MIH_C_LINK_DET_INFO_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Detected_indication(bb, &message); - -#ifdef MSCGEN_PYTOOL - g_msc_gen_buffer_index = 0; - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = MIH_C_SIG_STRENGTH2String(&linfoP->sig_strength, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index = sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nSINR %d\\nData rate %d", linfoP->sinr, linfoP->link_data_rate); -#endif - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Detected.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Detected.indication\\n%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Detected.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Detected.indication\\n%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_link_up_indication() ** - ** ** - ** Description: Sends a Link_Up.indication message to the MIHF. ** - ** ** - ** This notification is generated when a layer 2 connection ** - ** is established for the specified link interface. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** lidP: Link identifier ** - ** old_arP: Old access router link address ** - ** new_arP: New access router link address ** - ** flagP: Indicates whether the MN needs to change ** - ** IP Address in the new PoA ** - ** mobil_mngtP: Indicates the type of Mobility Management ** - ** Protocol supported by the new PoA ** - ** Others: g_link_id, g_mihf_id, ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_link_up_indication(MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_LINK_TUPLE_ID_T *lidP, - MIH_C_LINK_ADDR_T *old_arP, - MIH_C_LINK_ADDR_T *new_arP, - MIH_C_IP_RENEWAL_FLAG_T *flagP, - MIH_C_IP_MOB_MGMT_T *mobil_mngtP) -{ - MIH_C_Message_Link_Up_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; - - if (!(ralpriv->mih_supported_link_event_list & MIH_C_BIT_LINK_UP)) { - return; - } - - DEBUG(" Send MIH_C_MESSAGE_LINK_UP_INDICATION\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Up_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)2; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - memcpy(&message.primitive.LinkIdentifier, lidP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - - message.primitive.OldAccessRouter = old_arP; - message.primitive.NewAccessRouter = new_arP; - message.primitive.IPRenewalFlag = flagP; - message.primitive.MobilityManagementSupport = mobil_mngtP; - - message_total_length = MIH_C_Link_Message_Encode_Link_Up_indication(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_LINK_ID2String(&lidP->link_id, &g_msc_gen_buf[g_msc_gen_buffer_index]); - - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nOldAccessRouter="); - - if (old_arP) { - g_msc_gen_buffer_index += MIH_C_LINK_ADDR2String(old_arP, &g_msc_gen_buf[g_msc_gen_buffer_index]); - } else { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "null"); - } - - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nNewAccessRouter="); - - if (old_arP) { - g_msc_gen_buffer_index += MIH_C_LINK_ADDR2String(new_arP, &g_msc_gen_buf[g_msc_gen_buffer_index]); - } else { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "null"); - } - -#endif - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Up.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Up.indication\\n%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Up.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Up.indication\\n%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_link_down_indication() ** - ** ** - ** Description: Sends a Link_Down.indication message to the MIHF. ** - ** ** - ** This notification is generated when layer 2 connectivity ** - ** is lost. Layer 2 connectivity is lost explicitly in cases ** - ** where the MN initiates detach type procedures. In other ** - ** cases, the MN can infer loss of link connectivity due to ** - ** successive time-outs for acknowledgements of retransmit- ** - ** ted packets along with loss of reception of broadcast ** - ** frames. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** lidP: Link identifier ** - ** old_arP: Old access router link address ** - ** reason_codeP: Reason why the link went down ** - ** Others: g_link_id, g_mihf_id, ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_link_down_indication(MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_LINK_TUPLE_ID_T *lidP, - MIH_C_LINK_ADDR_T *old_arP, - MIH_C_LINK_DN_REASON_T *reason_codeP) -{ - MIH_C_Message_Link_Down_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; - - if (!(ralpriv->mih_supported_link_event_list & MIH_C_BIT_LINK_DOWN)) { - return; - } - - DEBUG(" Send MIH_C_MESSAGE_LINK_DOWN_INDICATION\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Going_Down_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)3; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - memcpy(&message.primitive.LinkIdentifier, lidP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - message.primitive.OldAccessRouter = old_arP; - memcpy(&message.primitive.ReasonCode, reason_codeP, - sizeof(MIH_C_LINK_DN_REASON_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Down_indication(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_LINK_ID2String(&lidP->link_id, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nOldAccessRouter="); - - if (old_arP) { - g_msc_gen_buffer_index += MIH_C_LINK_ADDR2String(old_arP, &g_msc_gen_buf[g_msc_gen_buffer_index]); - } else { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "null"); - } - - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nReasonCode="); - g_msc_gen_buffer_index += MIH_C_LINK_DN_REASON2String(reason_codeP, &g_msc_gen_buf[g_msc_gen_buffer_index]); -#endif - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Down.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Down.indication\\n%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Down.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Down.indication\\n%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_link_parameters_report_indication() ** - ** ** - ** Description: Sends a Link_Parameters_Report.indication message to the ** - ** MIHF. ** - ** ** - ** For each specified parameter, this notification is gene- ** - ** rated either at a predefined regular interval determined ** - ** by a user configurable timer or when it crosses a confi- ** - ** gured threshold. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** lidP: Link identifier ** - ** lparam_listP: List of link parameter reports ** - ** Others: g_link_id, g_mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_link_parameters_report_indication(MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_LINK_TUPLE_ID_T *lidP, - MIH_C_LINK_PARAM_RPT_LIST_T *lparam_listP) -{ - MIH_C_Message_Link_Parameters_Report_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; -#ifdef MSCGEN_PYTOOL - int i; -#endif - - if (!(ralpriv->mih_supported_link_event_list & MIH_C_BIT_LINK_PARAMETERS_REPORT)) { - return; - } - - DEBUG(" Send MIH_C_MESSAGE_LINK_PARAMETERS_REPORT_INDICATION\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Parameters_Report_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)5; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, lidP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - memcpy(&message.primitive.LinkParametersReportList_list, lparam_listP, sizeof(MIH_C_LINK_PARAM_RPT_LIST_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Parameters_Report_indication(bb, &message); - -#ifdef MSCGEN_PYTOOL - g_msc_gen_buffer_index = 0; - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index += MIH_C_LINK_ID2String(&lidP->link_id, &g_msc_gen_buf[g_msc_gen_buffer_index]); - - for (i = 0; i < lparam_listP->length; i++) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n"); - g_msc_gen_buffer_index += MIH_C_LINK_PARAM_RPT2String(&lparam_listP->val[i], &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - -#endif - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Parameters_Report.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Parameters_Report.indication\\n%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Parameters_Report.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Parameters_Report.indication\\n%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_link_going_down_indication() ** - ** ** - ** Description: Sends a Link_Going_Down.indication message to the MIHF. ** - ** ** - ** A Link_Going_Down event implies that a Link_Down is immi- ** - ** nent within a certain time interval. If Link_Down is NOT ** - ** received within specified time interval then actions due ** - ** to previous Link_Going_Down are ignored. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** lidP: Link identifier ** - ** timeP: The time interval (ms) at which the link ** - ** is expected to go down (0 if unknown) ** - ** lreasonP: Reason why the link is going to be down ** - ** Others: g_link_id, g_mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_link_going_down_indication(MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_LINK_TUPLE_ID_T *lidP, - MIH_C_UNSIGNED_INT2_T *timeP, - MIH_C_LINK_GD_REASON_T *lreasonP) -{ - MIH_C_Message_Link_Going_Down_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; - - if (!(ralpriv->mih_supported_link_event_list & MIH_C_BIT_LINK_GOING_DOWN)) { - return; - } - - DEBUG(" Send MIH_C_MESSAGE_LINK_GOING_DOWN_INDICATION\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Going_Down_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)6; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, lidP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - message.primitive.TimeInterval = *timeP; - memcpy(&message.primitive.LinkGoingDownReason, lreasonP, - sizeof(MIH_C_LINK_GD_REASON_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Going_Down_indication(bb, &message); - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Going_Down.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Going_Down.indication ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Going_Down.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Going_Down.indication --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/* - * ------------------------------------------------------------------------- - * Functions used to send MIH link command messages - * ------------------------------------------------------------------------- - */ - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_get_parameters_confirm() ** - ** ** - ** Description: Sends a Link_Get_Parameters.confirm message to the MIHF. ** - ** ** - ** This primitive is generated in response to a Link_Get_ ** - ** Parameters.request. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** statusP: Status of operation ** - ** lparam_listP: List of measurable link parameters and ** - ** their current values ** - ** lstates_listP: List of current link state information ** - ** ldesc_listP: List of link descriptors ** - ** Others: g_link_id, g_mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_get_parameters_confirm(MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_PARAM_LIST_T *lparam_listP, - MIH_C_LINK_STATES_RSP_LIST_T *lstates_listP, - MIH_C_LINK_DESC_RSP_LIST_T *ldesc_listP) -{ - MIH_C_Message_Link_Get_Parameters_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; -#ifdef MSCGEN_PYTOOL - int i; -#endif - - DEBUG(" Send MIH_C_MESSAGE_LINK_GET_PARAMETERS_CONFIRM\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Get_Parameters_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.LinkParametersStatusList_list = lparam_listP; - message.primitive.LinkStatesResponse_list = lstates_listP; - message.primitive.LinkDescriptorsResponse_list = ldesc_listP; - - message_total_length = MIH_C_Link_Message_Encode_Get_Parameters_confirm(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - - if (lparam_listP) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n LinkParametersStatusList="); - - for (i = 0; i < lparam_listP->length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_PARAM2String(&lparam_listP->val[i], &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], ", "); - } - } - - if (lstates_listP) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n LinkStatesResponseList="); - - for (i = 0; i < lstates_listP->length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_STATES_RSP2String(&lstates_listP->val[i], &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], ", "); - } - } - - if (ldesc_listP) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n LinkDescriptorsResponseList="); - - for (i = 0; i < ldesc_listP->length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_DESC_RSP2String(&ldesc_listP->val[i], &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], ", "); - } - } - -#endif - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Get_Parameters.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Get_Parameters.confirm\\nstatus=%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Get_Parameters.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Get_Parameters.confirm\\nstatus=%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_configure_thresholds_confirm() ** - ** ** - ** Description: Sends a Link_Configure_Thresholds.confirm message to the ** - ** MIHF. ** - ** ** - ** This primitive is generated in response to a Link_ ** - ** Configure_Thresholds.request. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** statusP: Status of operation ** - ** lstatus_listP: List of link configure status ** - ** Others: g_link_id, g_mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_configure_thresholds_confirm(MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_CFG_STATUS_LIST_T *lstatus_listP) -{ - MIH_C_Message_Link_Configure_Thresholds_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; -#ifdef MSCGEN_PYTOOL - int i; -#endif - - DEBUG(" Send MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_CONFIRM\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Configure_Thresholds_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)2; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.LinkConfigureStatusList_list = lstatus_listP; - - message_total_length = MIH_C_Link_Message_Encode_Configure_Thresholds_confirm(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n"); - - for (i = 0; i < lstatus_listP->length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_CFG_STATUS2String(&lstatus_listP->val[i], &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - -#endif - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Configure_Threshold.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Configure_Thresholds.confirm\\nstatus=%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Configure_Threshold.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Configure_Thresholds.confirm\\nstatus=%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_link_action_confirm() ** - ** ** - ** Description: Sends a Link_Action.confirm message to the MIHF. ** - ** ** - ** This primitive is generated to communicate the result of ** - ** the action executed on the link-layer connection. ** - ** ** - ** Inputs: tidP Transaction identifier ** - ** statusP: Status of operation ** - ** response_setP: List of discovered links and related ** - ** information ** - ** action_resultP: Specifies whether the link action was ** - ** successful ** - ** Others: g_link_id, g_mihf_id ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: g_msg_codec_send_buffer ** - ** ** - ***************************************************************************/ -void eRALlte_send_link_action_confirm(MIH_C_TRANSACTION_ID_T *tidP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_SCAN_RSP_LIST_T *response_setP, - MIH_C_LINK_AC_RESULT_T *action_resultP) -{ - MIH_C_Message_Link_Action_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; -#ifdef MSCGEN_PYTOOL - unsigned int index; -#endif - - DEBUG(" Send MIH_C_MESSAGE_LINK_ACTION_CONFIRM\n"); - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Action_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)3; - message.header.transaction_id = *tidP; - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.ScanResponseSet_list = response_setP; - message.primitive.LinkActionResult = action_resultP; - - message_total_length = MIH_C_Link_Message_Encode_Link_Action_confirm(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - - if (response_setP) { - for (index = 0; index < response_setP->length; index++) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nScan resp:"); - g_msc_gen_buffer_index += MIH_C_LINK_SCAN_RSP2String(&response_setP->val[index], &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - } - - if (action_resultP) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nAction result:"); - g_msc_gen_buffer_index += MIH_C_LINK_AC_RESULT2String2(action_resultP, &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - -#endif - - if (eRALlte_send_to_mih(bb->m_buffer, message_total_length) < 0) { - ERR(": Send Link_Action.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Action.confirm\\nstatus=%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Action.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Action.confirm\\nstatus=%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_mihf_connect() ** - ** ** - ** Description: Connects the RAL to the remote MIH Function. ** - ** The calling process should exit upon connection failure ** - ** in order to properly close the MIH-F socket file ** - ** descriptor and free the automatically allocated addrinfo ** - ** structure. ** - ** ** - ** Inputs: None ** - ** Others: g_mihf_ip_address, g_mihf_remote_port ** - ** g_ral_ip_address, ** - ** g_ral_listening_port_for_mihf ** - ** ** - ** Outputs: None ** - ** Return: 0 on success, -1 on failure ** - ** Others: g_sockd_mihf ** - ** ** - ***************************************************************************/ -int eRALlte_mihf_connect(ral_enb_instance_t instanceP) -{ - struct addrinfo info; /* endpoint information */ - struct addrinfo *addr, *rp; /* endpoint address */ - int rc; /* returned error code */ - int optval; /* socket option value */ - - unsigned char buf[sizeof(struct sockaddr_in6)]; - - /* - * Initialize the remote MIH-F endpoint address information - */ - memset(&info, 0, sizeof(struct addrinfo)); - info.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ - info.ai_socktype = SOCK_DGRAM; /* Datagram socket */ - info.ai_flags = 0; - info.ai_protocol = 0; /* Any protocol */ - - rc = getaddrinfo(g_enb_ral_obj[instanceP].mihf_ip_address, g_enb_ral_obj[instanceP].mihf_remote_port, &info, &addr); - - if (rc != 0) { - ERR(" getaddrinfo: %s\n", gai_strerror(rc)); - return -1; - } - - /* - * getaddrinfo() returns a linked list of address structures. - * Try each address until we successfully connect(2). If socket(2) - * (or connect(2)) fails, we (close the socket and) try the next address. - */ - for (rp = addr; rp != NULL; rp = rp->ai_next) { - g_enb_ral_obj[instance].mih_sock_desc = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - - if (g_enb_ral_obj[instance].mih_sock_desc < 0) { - continue; - } - - optval = 1; - setsockopt(g_enb_ral_obj[instance].mih_sock_desc, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); - - // Convert the RAL local network address - - if (rp->ai_family == AF_INET) { - /* IPv4 network address family */ - struct sockaddr_in *addr4 = NULL; - - DEBUG(" %s is an ipv4 address\n", g_enb_ral_obj[instanceP].mihf_ip_address); - addr4 = (struct sockaddr_in *)(&buf[0]); - addr4->sin_port = htons(atoi(g_enb_ral_obj[instanceP].ral_listening_port)); - addr4->sin_family = AF_INET; - rc = inet_pton(AF_INET, g_enb_ral_obj[instanceP].ral_ip_address, &addr4->sin_addr); - - } else if (rp->ai_family == AF_INET6) { - /* IPv6 network address family */ - struct sockaddr_in6 *addr6 = NULL; - - DEBUG(" %s is an ipv6 address\n", g_enb_ral_obj[instanceP].mihf_ip_address); - addr6 = (struct sockaddr_in6 *)(&buf[0]); - addr6->sin6_port = htons(atoi(g_enb_ral_obj[instanceP].ral_listening_port)); - addr6->sin6_family = AF_INET6; - rc = inet_pton(AF_INET, g_enb_ral_obj[instanceP].ral_ip_address, &addr6->sin6_addr); - } else { - ERR(" %s is an unknown address format %d\n", - g_enb_ral_obj[instanceP].mihf_ip_address, rp->ai_family); - return -1; - } - - if (rc < 0) { - // The network address convertion failed - ERR(" inet_pton(RAL IP address %s): %s\n", - g_enb_ral_obj[instanceP].ral_ip_address, strerror(rc)); - return -1; - } else if (rc == 0) { - // The network address is not valid - ERR(" RAL IP address %s is not valid\n", g_enb_ral_obj[instanceP].ral_ip_address); - return -1; - } - - // Bind the socket to the local RAL network address */ - rc = bind(g_enb_ral_obj[instance].mih_sock_desc, (const struct sockaddr *)buf, - sizeof(struct sockaddr_in)); - - if (rc < 0) { - ERR(" bind(RAL IP address %s): %s\n", g_enb_ral_obj[instanceP].ral_ip_address, strerror(errno)); - return -1; - } - - // Connect the socket to the remote MIH-F network address - if (connect(g_enb_ral_obj[instance].mih_sock_desc, rp->ai_addr, rp->ai_addrlen) == 0) { - NOTICE(" RAL [%s:%s] is now UDP-CONNECTED to MIH-F [%s:%s]\n", - g_enb_ral_obj[instanceP].ral_ip_address, g_enb_ral_obj[instanceP].ral_listening_port, - g_enb_ral_obj[instanceP].mihf_ip_address, g_enb_ral_obj[instanceP].mihf_remote_port); - break; - } - - // We failed to connect: - // Close the socket file descriptor and try to connect to an other address. - close(g_enb_ral_obj[instanceP].mih_sock_desc); - } - - // Unable to connect to a network address - if (rp == NULL) { - ERR(" Could not connect to MIH-F\n"); - return -1; - } - - freeaddrinfo(addr); - return 0; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_mih_link_process_message() ** - ** ** - ** Description: Processes messages received from the MIH-F. ** - ** ** - ** Inputs: None ** - ** Others: g_sockd_mihf ** - ** ** - ** Outputs: None ** - ** Return: Always return 0 ** - ** Others: g_msg_codec_recv_buffer ** - ** ** - ***************************************************************************/ -int eRALlte_mih_link_process_message(void) -{ - MIH_C_Message_Wrapper_t message_wrapper; - int nb_bytes_received ; - int nb_bytes_decoded ; - int total_bytes_to_decode ; - int status ; - Bit_Buffer_t *bb; - struct sockaddr_in udp_socket; - socklen_t sockaddr_len; - - - total_bytes_to_decode = 0; - nb_bytes_received = 0; - - bb = new_BitBuffer_0(); - - nb_bytes_received = recvfrom(g_sockd_mihf, - (void *)g_msg_codec_recv_buffer, - MSG_CODEC_RECV_BUFFER_SIZE, - 0, - (struct sockaddr *) &udp_socket, - &sockaddr_len); - - if (nb_bytes_received > 0) { - DEBUG(" %s Received %d bytes\n", __FUNCTION__, nb_bytes_received); - eRALlte_print_buffer(g_msg_codec_recv_buffer, nb_bytes_received); - total_bytes_to_decode += nb_bytes_received; - BitBuffer_wrap(bb, g_msg_codec_recv_buffer, total_bytes_to_decode); - /* Decode the message received from the MIHF */ - status = eRALlte_mih_link_msg_decode(bb, &message_wrapper); - - if (status == MIH_MESSAGE_DECODE_OK) { - nb_bytes_decoded = BitBuffer_getPosition(bb); - - if (nb_bytes_decoded > 0) { - total_bytes_to_decode = total_bytes_to_decode - nb_bytes_decoded; - - // if remaining bytes to decode - if (total_bytes_to_decode > 0) { - //shift left bytes in buffer - memcpy(g_msg_codec_recv_buffer, &g_msg_codec_recv_buffer[nb_bytes_decoded], nb_bytes_decoded); - - //shift left again bytes in buffer - if (total_bytes_to_decode > nb_bytes_decoded) { - memcpy(&g_msg_codec_recv_buffer[nb_bytes_decoded], &g_msg_codec_recv_buffer[nb_bytes_decoded], total_bytes_to_decode - nb_bytes_decoded); - } - - // not necessary - memset(&g_msg_codec_recv_buffer[total_bytes_to_decode], 0 , MSG_CODEC_RECV_BUFFER_SIZE - total_bytes_to_decode); - - } - } - - // data could not be decoded - } else if (status == MIH_MESSAGE_DECODE_FAILURE) { - memset(g_msg_codec_recv_buffer, 0, MSG_CODEC_RECV_BUFFER_SIZE); - total_bytes_to_decode = 0; - } else if (status == MIH_MESSAGE_DECODE_TOO_SHORT) { - } else if (status == MIH_MESSAGE_DECODE_BAD_PARAMETER) { - } - } - - free_BitBuffer(bb); - return 0; -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRALlte_print_buffer() ** - ** ** - ** Description: Print the content of a buffer in hexadecimal. ** - ** ** - ** Inputs: bufferP: Pointer to the buffer to print ** - ** lengthP: Length of the buffer to print ** - ** Others: g_msg_codec_print_buffer ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -static void eRALlte_print_buffer(const u_int8_t * bufferP, int lenP) -{ - char c; - unsigned int buffer_index = 0; - unsigned int index; - unsigned int octet_index = 0; - unsigned long char_index = 0; - - if (bufferP == NULL) { - return; - } - - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index],"\n------+-------------------------------------------------+------------------+\n"); - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " | 0 1 2 3 4 5 6 7 8 9 a b c d e f | 0123456789abcdef |\n"); - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], "------+-------------------------------------------------+------------------+\n"); - - for (octet_index = 0; octet_index < lenP; octet_index++) { - if ((octet_index % 16) == 0) { - if (octet_index != 0) { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " | "); - - for (char_index = octet_index - 16; char_index < octet_index; char_index++) { - c = (char) bufferP[char_index] & 0177; - - if (iscntrl(c) || isspace(c)) { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " "); - } else { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], "%c", c); - } - } - - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " |\n"); - } - - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " %04d |", octet_index); - } - - /* - * Print every single octet in hexadecimal form - */ - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " %02x", (u_int8_t)(bufferP[octet_index] & 0x00FF)); - } - - /* - * Append enough spaces and put final pipe - */ - if ((lenP % 16) > 0) { - for (index = (octet_index % 16); index < 16; ++index) { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " "); - } - } - - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " | "); - - for (char_index = (octet_index / 16) * 16; char_index < octet_index; char_index++) { - c = (char) bufferP[char_index] & 0177; - - if (iscntrl(c) || isspace(c)) { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " "); - } else { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], "%c", c); - } - } - - if ((lenP % 16) > 0) { - for (index = (octet_index % 16); index < 16; ++index) { - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " "); - } - } - - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], " |\n"); - buffer_index += sprintf(&g_msg_codec_print_buffer[buffer_index], "------+-------------------------------------------------+------------------+\n"); - DEBUG(g_msg_codec_print_buffer); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_send_to_mih() ** - ** ** - ** Description: Sends a buffered message to the MIH-F. ** - ** ** - ** Inputs: bufferP: Pointer to the buffered buffer to send ** - ** lenP: Length of the buffered buffer to send ** - ** Others: g_sockd_mihf ** - ** ** - ** Outputs: None ** - ** Return: The number of bytes actually sent ** - ** Others: None ** - ** ** - ***************************************************************************/ -static int eRALlte_send_to_mih(const u_int8_t *bufferP, int lenP) -{ - int result; - eRALlte_print_buffer(bufferP, lenP); - result = send(g_sockd_mihf, (const void *)bufferP, lenP, 0); - - if (result != lenP) { - ERR(" %s : %d bytes failed, returned %d: %s\n", - __FUNCTION__, lenP, result, strerror(errno)); - } - - return result; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_mih_link_msg_decode() ** - ** ** - ** Description: Decode messages received from the MIH-F. ** - ** ** - ** Inputs: bbP: Pointer to the buffer to decode ** - ** Others: None ** - ** ** - ** Outputs: message_wrapperP: ** - ** Pointer to the message wrapper ** - ** Return: < 0 on failure, 0 otherwise ** - ** Others: None ** - ** ** - ***************************************************************************/ -static int eRALlte_mih_link_msg_decode(Bit_Buffer_t* bbP, - MIH_C_Message_Wrapper_t *message_wrapperP) -{ - int status = MIH_MESSAGE_DECODE_FAILURE; - MIH_C_HEADER_T header; - MIH_C_STATUS_T mih_status; -#ifdef MSCGEN_PYTOOL - char msg_src[32]; - char msg_dst[32]; - int i; -#endif - - if ((bbP != NULL) && (message_wrapperP != NULL)) { - /* - * Decode MIH protocol header - */ - status = MIH_C_Link_Header_Decode(bbP, &header); - - if (status == MIH_HEADER_DECODE_TOO_SHORT) { - return MIH_MESSAGE_DECODE_TOO_SHORT; - } else if (status == MIH_HEADER_DECODE_FAILURE) { - return MIH_MESSAGE_DECODE_FAILURE; - } else if (status == MIH_HEADER_DECODE_BAD_PARAMETER) { - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - message_wrapperP->message_id = MIH_C_MESSAGE_ID(header.service_identifier, header.operation_code, header.action_identifier); - - /* - * Decode MIH primitives - */ - switch (message_wrapperP->message_id) { - - case MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_REQUEST_ID: - /* - * This primitive is generated by the MIHF when it needs to - * receive link-layer event notifications and learn about which - * link-layer commands the lower layer can support. - * The recipient responds immediately with Link_Capability_ - * Discover.confirm primitive. - */ - DEBUG(" %s Received MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_capability_discover_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Capability_Discover.request */ - status = MIH_C_Link_Message_Decode_Link_Capability_Discover_request(bbP, &message_wrapperP->_union_message.link_capability_discover_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_capability_discover_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_capability_discover_request.destination), msg_dst); - NOTICE("[MSC_MSG][%s][%s][--- Link_Capability_Discover.request --->][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - - /* Process Link_Capability_Discover.request */ - MIH_C_Link_Message_Link_Capability_Discover_request2String(&message_wrapperP->_union_message.link_capability_discover_request, g_msg_print_buffer); - DEBUG(" %s", g_msg_print_buffer); - mih_status = MIH_C_STATUS_SUCCESS; - - /* Send Link_Capability_Discover.confirm */ - eRALlte_send_capability_discover_confirm(&message_wrapperP->_union_message.link_capability_discover_request.header.transaction_id, - &mih_status, - &ralpriv->mih_supported_link_event_list, - &ralpriv->mih_supported_link_command_list); - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_capability_discover_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_capability_discover_request.destination), msg_dst); - NOTICE("[MSC_MSG][%s][%s][--- Link_Capability_Discover.request\\nERR DECODE ---x][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - case MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_REQUEST_ID: - /* - * This primitive is generated by a subscriber such as the MIHF - * that is seeking to receive event indications from different - * link-layer technologies. - * The recipient responds immediately with Link_Event_Subscribe. - * confirm primitive. - */ - DEBUG(" %s Received MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_event_subscribe_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Event_Subscribe.request */ - status = MIH_C_Link_Message_Decode_Link_Event_Subscribe_request(bbP, &message_wrapperP->_union_message.link_event_subscribe_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_subscribe_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_subscribe_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - MIH_C_LINK_EVENT_LIST2String2(&message_wrapperP->_union_message.link_event_subscribe_request.primitive.RequestedLinkEventList, g_msc_gen_buf); - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Subscribe.request\\n%s --->][%s]\n", - getTimeStamp4Log(), - msg_src, - g_msc_gen_buf, - msg_dst); -#endif - - /* Process Link_Event_Subscribe.request */ - eRALlte_subscribe_request(&message_wrapperP->_union_message.link_event_subscribe_request); - - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_subscribe_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_subscribe_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - MIH_C_LINK_EVENT_LIST2String2(&message_wrapperP->_union_message.link_event_subscribe_request.primitive.RequestedLinkEventList, g_msc_gen_buf); - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Subscribe.request\\nERR DECODE ---x][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - case MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_REQUEST_ID: - /* - * This primitive is generated by a subscriber such as the MIHF - * that is seeking to unsubscribe from an already subscribed set - * of events. - * The recipient responds immediately with Link_Event_ - * Unsubscribe.confirm primitive. - */ - DEBUG(" %s Received MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_event_unsubscribe_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Event_Unsubscribe.request */ - status = MIH_C_Link_Message_Decode_Link_Event_Unsubscribe_request(bbP, &message_wrapperP->_union_message.link_event_unsubscribe_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_unsubscribe_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_unsubscribe_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - MIH_C_LINK_EVENT_LIST2String2(&message_wrapperP->_union_message.link_event_unsubscribe_request.primitive.RequestedLinkEventList, g_msc_gen_buf); - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Unsubscribe.request\\n%s --->][%s]\n", - getTimeStamp4Log(), - msg_src, - g_msc_gen_buf, - msg_dst); -#endif - - /* Process Link_Event_Unsubscribe.request */ - eRALlte_unsubscribe_request(&message_wrapperP->_union_message.link_event_unsubscribe_request); - - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_unsubscribe_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_unsubscribe_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - MIH_C_LINK_EVENT_LIST2String2(&message_wrapperP->_union_message.link_event_unsubscribe_request.primitive.RequestedLinkEventList, g_msc_gen_buf); - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Unsubscribe.request\\nERR DECODE ---x][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - case MIH_C_MESSAGE_LINK_GET_PARAMETERS_REQUEST_ID: - /* - * This primitive is generated by the MIHF to obtain the current - * value of a set of link parameters from a link. - * The recipient link responds with Link_Get_Parameters.confirm - * primitive. - */ - DEBUG(" %s Received MIH_C_MESSAGE_LINK_GET_PARAMETERS_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_get_parameters_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Get_Parameters.request */ - status = MIH_C_Link_Message_Decode_Link_Get_Parameters_request(bbP, &message_wrapperP->_union_message.link_get_parameters_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_get_parameters_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_get_parameters_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - - for (i = 0; i < message_wrapperP->_union_message.link_get_parameters_request.primitive.LinkParametersRequest_list.length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_PARAM_TYPE2String(&message_wrapperP->_union_message.link_get_parameters_request.primitive.LinkParametersRequest_list.val[i], - &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n Link states request="); - g_msc_gen_buffer_index += MIH_C_LINK_STATES_REQ2String2(&message_wrapperP->_union_message.link_get_parameters_request.primitive.LinkStatesRequest, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n Link desc request="); - g_msc_gen_buffer_index += MIH_C_LINK_DESC_REQ2String2(&message_wrapperP->_union_message.link_get_parameters_request.primitive.LinkDescriptorsRequest, &g_msc_gen_buf[g_msc_gen_buffer_index]); - - NOTICE("[MSC_MSG][%s][%s][--- Link_Get_Parameters.request\\n%s --->][%s]\n", - getTimeStamp4Log(), - msg_src, - g_msc_gen_buf, - msg_dst); -#endif - - /* Process Link_Get_Parameters.request */ - eRALlte_get_parameters_request(&message_wrapperP->_union_message.link_get_parameters_request); - - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_get_parameters_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_get_parameters_request.destination), msg_dst); - NOTICE("[MSC_MSG][%s][%s][--- Link_Get_Parameters.request\\nERR DECODE ---x][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - case MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_REQUEST_ID: - /* - * This primitive is generated by an MIHF that needs to set - * threshold values for different link parameters. - * The recipient responds immediately with Link_Configure_ - * Thresholds.confirm primitive. - */ - DEBUG(" %s Received MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_configure_thresholds_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Configure_Thresholds.request */ - status = MIH_C_Link_Message_Decode_Link_Configure_Thresholds_request(bbP, &message_wrapperP->_union_message.link_configure_thresholds_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_configure_thresholds_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_configure_thresholds_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - - for (i = 0; i < message_wrapperP->_union_message.link_configure_thresholds_request.primitive.LinkConfigureParameterList_list.length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_CFG_PARAM2String(&message_wrapperP->_union_message.link_configure_thresholds_request.primitive.LinkConfigureParameterList_list.val[i], - &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - - NOTICE("[MSC_MSG][%s][%s][--- Link_Configure_Thresholds.request\\n%s --->][%s]\n", - getTimeStamp4Log(), - msg_src, - g_msc_gen_buf, - msg_dst); -#endif - - /* Process Link_Configure_Thresholds.request */ - eRALlte_configure_thresholds_request(&message_wrapperP->_union_message.link_configure_thresholds_request); - - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_configure_thresholds_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_configure_thresholds_request.destination), msg_dst); - NOTICE("[MSC_MSG][%s][%s][--- Link_Configure_Thresholds.request\\nERR DECODE ---x][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - case MIH_C_MESSAGE_LINK_ACTION_REQUEST_ID: - /* - * This primitive is used by the MIHF to request an action on a - * link-layer connection to enable optimal handling of link- - * layer resources for the purpose of handovers. - * The MIHF generates this primitive upon request from the MIH - * user to perform an action on a pre-defined link-layer - * connection. - */ - DEBUG(" %s Received MIH_C_MESSAGE_LINK_ACTION_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_action_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - - /* Decode Link_Action.request */ - status = MIH_C_Link_Message_Decode_Link_Action_request(bbP, &message_wrapperP->_union_message.link_action_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_action_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_action_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_LINK_ACTION2String(&message_wrapperP->_union_message.link_action_request.primitive.LinkAction, g_msc_gen_buf); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nExecution Delay=%d", message_wrapperP->_union_message.link_action_request.primitive.ExecutionDelay); - - if (message_wrapperP->_union_message.link_action_request.primitive.PoALinkAddress != NULL) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nPoALinkAddress="); - g_msc_gen_buffer_index += MIH_C_LINK_ADDR2String(message_wrapperP->_union_message.link_action_request.primitive.PoALinkAddress, &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - - NOTICE("[MSC_MSG][%s][%s][--- Link_Action.request\\n%s --->][%s]\n", - getTimeStamp4Log(), - msg_src, - g_msc_gen_buf, - msg_dst); -#endif - - /* Process Link_Action.request */ - eRALlte_action_request(&message_wrapperP->_union_message.link_action_request); - - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_action_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_action_request.destination), msg_dst); - NOTICE("[MSC_MSG][%s][%s][--- Link_Action.request\\nERR DECODE --->][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - default: - WARNING(" UNKNOWN MESSAGE ID SID %d, OP_CODE %d, AID %d\n", header.service_identifier, header.operation_code, header.action_identifier); - status = MIH_MESSAGE_DECODE_FAILURE; - } - } else { - status = MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - return status; -} diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_parameters.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_parameters.c deleted file mode 100644 index 29d7c4bbb5..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_parameters.c +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include "eRALlte_parameters.h" - -#include "eRALlte_mih_msg.h" - -/****************************************************************************/ -/******************* G L O C A L D E F I N I T I O N S *****************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRALlte_get_parameters_request() ** - ** ** - ** Description: Processes the Link_Get_Parameters.request message and ** - ** sends a LinK_Get_Parameters.confirm message to the MIHF. ** - ** ** - ** Inputs: msgP: Pointer to the received message ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void eRALlte_get_parameters_request(MIH_C_Message_Link_Get_Parameters_request_t* msgP) -{ - MIH_C_STATUS_T status = MIH_C_STATUS_REJECTED; - - /* Get parameters link command is not supported at the network side */ - DEBUG(" Get Parameters request is not supported by the network\n"); - eRALlte_send_get_parameters_confirm(&msgP->header.transaction_id, - &status, NULL, NULL, NULL); -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_process.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_process.c deleted file mode 100644 index ba13b04f66..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_process.c +++ /dev/null @@ -1,546 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include "eRALlte_variables.h" -#include "eRALlte_proto.h" - -/****************************************************************************/ -/******************* G L O C A L D E F I N I T I O N S *****************/ -/****************************************************************************/ - -extern int eRALlte_action_save_flow_id(MIH_C_FLOW_ID_T* flowId, int cnxid); - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -static void _eRALlte_process_clean_pending_mt(void); -static void _eRALlte_process_waiting_RB(int mt_ix); - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRALlte_process_find_channel() ** - ** ** - ** Description: Returns the Mobile Terminal index and the Radio Bearer ** - ** channel index for the specified Connection identifier. ** - ** ** - ** Inputs: cnxid: Connection identifier ** - ** Others: ralpriv ** - ** ** - ** Outputs: mt_ix: Mobile Terminal index ** - ** ch_ix: Radio Bearer channel index ** - ** Return: 0 if no MT and RB channel indexes exist ** - ** for the specified Connection identifier. ** - ** 1 otherwise. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRALlte_process_find_channel(unsigned int cnxid, int* mt_ix, int* ch_ix) -{ - int mt, ch; - int found = 0; - - DEBUG(" %s : cnxid = %d\n", __FUNCTION__, cnxid); - - for (mt = 0; !found && (mt < RAL_MAX_MT); mt++) { - for (ch = 0; ch < RAL_MAX_RB; ch++) { - if (ralpriv->mt[mt].radio_channel[ch].cnx_id == cnxid) { - found = 1; - *mt_ix = mt; - *ch_ix = ch; - break; - } - } - } - - if (!found) { - *mt_ix = RAL_MAX_MT; - *ch_ix = 0; - } - - DEBUG (" %s : return %d (mt=%d, ch=%d)\n" , __FUNCTION__, found, *mt_ix, *ch_ix); - return found; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_process_find_new_channel() ** - ** ** - ** Description: Returns the index of the first available Radio Bearer ** - ** channel for the specified Mobile Terminal identifier. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: The index of the first available RB chan- ** - ** nel; RAL_MAX_RB if no any RB channel is ** - ** available. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRALlte_process_find_new_channel(int mt_ix) -{ - int ch_ix; - - DEBUG(" %s : mt_ix = %d\n", __FUNCTION__, mt_ix); - - for (ch_ix = 0; ch_ix < RAL_MAX_RB; ch_ix++) { - if (ralpriv->mt[mt_ix].radio_channel[ch_ix].cnx_id == 0) { - break; - } - } - - DEBUG (" %s : return %d\n" , __FUNCTION__, ch_ix); - return ch_ix; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_process_clean_channel() ** - ** ** - ** Description: Cleans data of the specified Radio Bearer channel. ** - ** ** - ** Inputs: None ** - ** Others: None ** - ** ** - ** Outputs: channel: Channel data to clean ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void eRALlte_process_clean_channel(struct ral_lte_channel* channel) -{ - DEBUG(" %s : cnx_id = %d, rbId = %d\n", __FUNCTION__, - channel->cnx_id, channel->rbId); - memset(channel, 0, sizeof (struct ral_lte_channel)); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_process_mt_addr_to_string() ** - ** ** - ** Description: Display the specified IPv6 address. ** - ** ** - ** Inputs: ip_addr: The IP address ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: Pointer to the string buffer. ** - ** Others: None ** - ** ** - ***************************************************************************/ -char* eRALlte_process_mt_addr_to_string(const unsigned char* ip_addr) -{ - static char buffer[40]; - int i, index = 0; - - for (i = 0; i < 16; i++) { - index += sprintf(&buffer[index], "%.2hX", ip_addr[i]); - - if (i % 2) buffer[index++] = ':'; - } - - buffer[--index] = '\0'; - return buffer; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_process_mt_addr_to_l2id() ** - ** ** - ** Description: Convert the specified IP address to Layer 2 identifier. ** - ** ** - ** Inputs: mt_addr: MT's IP address ** - ** Others: None ** - ** ** - ** Outputs: l2id Layer 2 identifier ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void eRALlte_process_mt_addr_to_l2id(const unsigned char* mt_addr, unsigned int* l2id) -{ - if ( !(mt_addr) || !(l2id) ) { - ERR(" %s : input parameter is NULL\n", __FUNCTION__); - return; - } - - l2id[0] = mt_addr[0]+256 *(mt_addr[1]+256*(mt_addr[2]+256*(mt_addr[3]))); - l2id[1] = mt_addr[4]+256 *(mt_addr[5]+256*(mt_addr[6]+256*(mt_addr[7]))); -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_process_cmp_mt_addr() ** - ** ** - ** Description: Compares MT's IP address to the specified L2 identifier. ** - ** ** - ** Inputs: mt_addr: MT's IP address ** - ** l2id Layer 2 identifier ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: 0 if the MT's IP address matches the L2 ** - ** identifier, 1 otherwise. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRALlte_process_cmp_mt_addr(const char* mt_addr, const char* l2id) -{ - int i; - - for (i = 0; i < 8; i++) { - if ((uint8_t)l2id[i] != (uint8_t)mt_addr[i+8]) { - return 0; - } - } - - return 1; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_process_find_mt_by_addr() ** - ** ** - ** Description: Returns the index of the Mobile Terminal with the ** - ** specified IP address. ** - ** ** - ** Inputs: mt_addr: MT's IP address ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: The MT's index in the list of MTs; ** - ** RAL_MAX_MT if not found. ** - ** Others: None ** - ** ** - ***************************************************************************/ -int eRALlte_process_find_mt_by_addr(const char* mt_addr) -{ - int mt_ix; - - for (mt_ix = 0; mt_ix < RAL_MAX_MT; mt_ix++) { - const char* l2id = (const char*)(&ralpriv->mt[mt_ix].ipv6_l2id[0]); - int i; - - for (i = 0; i < 8; i++) { - if ((uint8_t)l2id[i] != (uint8_t)mt_addr[i+8]) { - break; - } - } - - if (i == 8) { - break; - } - } - - DEBUG (" %s : return %d\n" , __FUNCTION__, mt_ix); - return mt_ix; -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_process_verify_pending_mt_status() ** - ** ** - ** Description: Checks the pending MT connection status and simulates RB ** - ** setup if it is ready for Radio Bearer establishment. ** - ** ** - ** Inputs: None ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void eRALlte_process_verify_pending_mt_status(void) -{ - int mt_ix; - - if (!ralpriv->pending_mt_timer) { - DEBUG(" Pending MT timer expired\n"); -#ifdef RAL_REALTIME - _eRALlte_process_clean_pending_mt(); -#endif -#ifdef RAL_DUMMY - DEBUG(" SIMULATE MT arrival\n"); - mt_ix = eRALlte_NAS_update_MTs_list(); - DEBUG(" SIMULATE RB setup\n"); - _eRALlte_process_waiting_RB(mt_ix); -#endif - } else { -#ifdef RAL_REALTIME - - if (!( ralpriv->pending_mt_timer % 10)) { - /* Get the list of MTs in the driver waiting for pending - * RB establishment */ - TQAL_process_NAS_message(IO_OBJ_CNX, IO_CMD_LIST, 0, 0); - TQAL_process_NAS_message(IO_OBJ_RB, IO_CMD_LIST, 0, 0); - /* Check if the pending MT is in the list */ - mt_ix = eRALlte_process_find_mt_by_addr((char*)ralpriv->pending_mt.ipv6_addr); - - if ( (mt_ix < RAL_MAX_MT) && - (ralpriv->mt[mt_ix].mt_state == RB_CONNECTED)) { - /* The pending MT is ready for RB establishment */ - _eRALlte_process_waiting_RB(mt_ix); - } - } - -#endif - } -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_process_map_qos() ** - ** ** - ** Description: Performs mapping of reserved bit rate to Radio QoS class, ** - ** and mapping of traffic class to DCSP. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** ch_ix: Radio Bearer channel index ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: 1 if the requested reserved bit rate and ** - ** traffic class are supported and their ** - ** mapping to Radio Qos class and DSCP ** - ** succeed. 0 otherwise. ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -int eRALlte_process_map_qos(int mt_ix, int ch_ix) -{ - int resBitrateDL = 0, resBitrateUL = 0; - struct ral_lte_channel *currChannel; - - /* - * Map for multicast flow - */ - if (mt_ix == RAL_MAX_MT) { - currChannel = &(ralpriv->mcast.radio_channel); - - /* multicast - reserved bit rate */ - resBitrateDL = (int)currChannel->resBitrate[1]; - - if (resBitrateDL <= RAL_BITRATE_128k) { - currChannel->RadioQoSclass = 20; - } else if (resBitrateDL <= RAL_BITRATE_256k) { - currChannel->RadioQoSclass = 21; - } else if (resBitrateDL <= RAL_BITRATE_384k) { - currChannel->RadioQoSclass = 22; - } else { - ERR (" %s : Invalid requested resBitrate %d - Request will be rejected.\n", __FUNCTION__, resBitrateDL); - return 0; - } - - /* multicast - DSCP */ - if (currChannel->classId[1] < 64) { - currChannel->dscpDL = currChannel->classId[1]; - } else { - ERR (" %s : DSCP %d > 63 - NOT SUPPORTED - Request will be rejected.\n", __FUNCTION__, currChannel->classId[1]); - return 0; - } - - DEBUG (" QoS Mapping : Requested radio QoS class %d, DSCP DL %d\n", - currChannel->RadioQoSclass, - currChannel->dscpDL); - } - - /* - * Map for unicast flow - */ - else { - currChannel = &(ralpriv->mt[mt_ix].radio_channel[ch_ix]); - - /* unicast - reserved bit rate - CONVERSATIONAL */ - resBitrateDL = (int)currChannel->resBitrate[1]; - resBitrateUL = (int)currChannel->resBitrate[0]; - - if ((resBitrateDL <= RAL_BITRATE_32k) && - (resBitrateUL <= RAL_BITRATE_32k)) { - currChannel->RadioQoSclass = 1; - } else if ((resBitrateDL <= RAL_BITRATE_64k) && - (resBitrateUL <= RAL_BITRATE_64k)) { - currChannel->RadioQoSclass = 2; - } else if ((resBitrateDL <= RAL_BITRATE_128k) && - (resBitrateUL <= RAL_BITRATE_128k)) { - currChannel->RadioQoSclass = 3; - } else if ((resBitrateDL <= RAL_BITRATE_256k) && - (resBitrateUL <= RAL_BITRATE_256k)) { - currChannel->RadioQoSclass = 4; - } else if ((resBitrateDL <= RAL_BITRATE_320k) && - (resBitrateUL <= RAL_BITRATE_320k)) { - currChannel->RadioQoSclass = 5; - } else if ((resBitrateDL >= RAL_BITRATE_384k) && - (resBitrateDL <= RAL_BITRATE_440k) && - (resBitrateUL <= RAL_BITRATE_64k)) { - currChannel->RadioQoSclass = 14; - } else { - ERR (" %s : Invalid requested resBitrate %d , %d - Request will be rejected\n", __FUNCTION__, resBitrateDL, resBitrateUL); - return 0; - } - - /* unicast - DSCP */ - if ((currChannel->classId[0] < 64) && - (currChannel->classId[1] < 64)) { - currChannel->dscpUL = currChannel->classId[0]; - currChannel->dscpDL = currChannel->classId[1]; - } else { - ERR (" %s : DSCP > 63 - NOT SUPPORTED - Request will be rejected.\n", __FUNCTION__); - return 0; - } - - DEBUG (" QoS Mapping : Requested radio QoS class %d, DSCP UL %d, DSCP DL %d\n", currChannel->RadioQoSclass, currChannel->dscpUL, currChannel->dscpDL); - } - - return 1; -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: _eRALlte_process_waiting_RB() ** - ** ** - ** Description: Allocates a new Radio Bearer parameters to the specified ** - ** Mobile Terminal which was pending for RB establishment, ** - ** and sends RB establishment request to the NAS sublayer. ** - ** ** - ** Inputs: mt_ix: Mobile Terminal index ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -static void _eRALlte_process_waiting_RB(int mt_ix) -{ - struct ral_lte_channel *currChannel; - struct ral_lte_channel *pendingChannel; - int ch_ix, f_ix; - int dir, mapping_result, rc = -1; - - DEBUG(" Establishment of pending RB now starting...\n"); - ch_ix = eRALlte_process_find_new_channel(mt_ix); - - if (ch_ix == RAL_MAX_RB) { - DEBUG(" No RB available in MT - Deleting request data\n"); - _eRALlte_process_clean_pending_mt(); - return; - } - - pendingChannel = &(ralpriv->pending_mt.radio_channel[0]); - currChannel = &(ralpriv->mt[mt_ix].radio_channel[ch_ix]); - - currChannel->cnx_id = (RAL_MAX_RB_PER_UE*mt_ix)+ch_ix+1; - currChannel->rbId = RAL_DEFAULT_RAB_ID+ch_ix; - currChannel->multicast = 0; - DEBUG(" mt_ix %d, ch_ix %d, cnx_id %d, rbId %d\n", - mt_ix, ch_ix, currChannel->cnx_id, currChannel->rbId); - memcpy((char *)&(ralpriv->mt[mt_ix].ipv6_addr), - (char *)&(ralpriv->pending_mt.ipv6_addr), 16); - DEBUG (" MT's address = %s\n", - eRALlte_process_mt_addr_to_string(ralpriv->mt[mt_ix].ipv6_addr)); - - /* Save the pending data flow identifier into the list of active data flows */ - f_ix = eRALlte_action_save_flow_id(&ralpriv->pending_req_fid, currChannel->cnx_id); - - if (f_ix < 0) { - DEBUG(" No RB available - Deleting request data\n"); - _eRALlte_process_clean_pending_mt(); - return; - } - - /* Store resource parameters of the pending MT */ - for (dir = 0; dir < 2; dir++) { - currChannel->flowId[dir] = f_ix; - currChannel->classId[dir]= pendingChannel->classId[dir] ; - currChannel->resBitrate[dir] = pendingChannel->resBitrate[dir]; - currChannel->meanBitrate[dir] = pendingChannel->meanBitrate[dir]; - currChannel->bktDepth[dir] = pendingChannel->bktDepth[dir]; - currChannel->pkBitrate[dir] = pendingChannel->pkBitrate[dir]; - currChannel->MTU[dir] = pendingChannel->MTU[dir]; - DEBUG(" qos value : DIR %d, flowId %d, classId %d, resBitrate %.1f \n", - dir, currChannel->flowId[dir], currChannel->classId[dir], - currChannel->resBitrate[dir]); - } - - /* Map Qos */ - mapping_result = eRALlte_process_map_qos(mt_ix, ch_ix); - - if (mapping_result) { -#ifdef RAL_DUMMY - rc = eRALlte_NAS_send_rb_establish_request(mt_ix, ch_ix); -#endif -#ifdef RAL_REALTIME - rc = TQAL_process_NAS_message(IO_OBJ_RB, IO_CMD_ADD, mt_ix, ch_ix); -#endif - } - - if (rc < 0) { - /* Failed to send RB establishment request; release new RB data */ - eRALlte_process_clean_channel(currChannel); - } else { - /* RB establishment request has been sent; release pending MT data */ - ralpriv->pending_req_flag = 0; - _eRALlte_process_clean_pending_mt(); - } -} - -/**************************************************************************** - ** ** - ** Name: _eRALlte_process_clean_pending_mt() ** - ** ** - ** Description: Deletes previously stored pending MT data. ** - ** ** - ** Inputs: None ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -static void _eRALlte_process_clean_pending_mt(void) -{ - memset(ralpriv->pending_mt.ipv6_addr, 0 , 16); - eRALlte_process_clean_channel(&ralpriv->pending_mt.radio_channel[0]); - - ralpriv->pending_mt_timer = -1; - DEBUG(" Pending MT data deleted\n"); -} - diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_subscribe.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_subscribe.c deleted file mode 100644 index cbb8b1ace2..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_subscribe.c +++ /dev/null @@ -1,132 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include "eRALlte_subscribe.h" - -#include "eRALlte_mih_msg.h" -#include "eRALlte_variables.h" - -/****************************************************************************/ -/******************* G L O C A L D E F I N I T I O N S *****************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRALlte_subscribe_request() ** - ** ** - ** Description: Subscribes the MIH-F to receive specified link event ** - ** indications and sends Link Event Subscribe confirmation ** - ** to the MIH-F. ** - ** ** - ** Inputs: msgP: Pointer to the received MIH message ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -void eRALlte_subscribe_request(MIH_C_Message_Link_Event_Subscribe_request_t* msgP) -{ - MIH_C_STATUS_T status = MIH_C_STATUS_REJECTED; - - /* Check whether the action request is supported */ - if (ralpriv->mih_supported_link_command_list & MIH_C_BIT_LINK_EVENT_SUBSCRIBE) { - MIH_C_LINK_EVENT_LIST_T mih_subscribed_req_event_list; - - ralpriv->mih_subscribe_req_event_list |= (msgP->primitive.RequestedLinkEventList & ralpriv->mih_supported_link_event_list); - - mih_subscribed_req_event_list = ralpriv->mih_subscribe_req_event_list & msgP->primitive.RequestedLinkEventList; - - status = MIH_C_STATUS_SUCCESS; - - eRALlte_send_event_subscribe_confirm(&msgP->header.transaction_id, - &status, - &mih_subscribed_req_event_list); - } else { - eRALlte_send_event_subscribe_confirm(&msgP->header.transaction_id, - &status, - NULL); - } -} - -/**************************************************************************** - ** ** - ** Name: eRALlte_unsubscribe_request() ** - ** ** - ** Description: Unsubscribes the MIH-F to receive specified link event ** - ** indications and sends Link Event Unsubscribe confirmation ** - ** to the MIH-F. ** - ** ** - ** Inputs: msgP: Pointer to the received MIH message ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: ralpriv ** - ** ** - ***************************************************************************/ -void eRALlte_unsubscribe_request(MIH_C_Message_Link_Event_Unsubscribe_request_t* msgP) -{ - MIH_C_STATUS_T status = MIH_C_STATUS_REJECTED; - - /* Check whether the action request is supported */ - if (ralpriv->mih_supported_link_command_list & MIH_C_BIT_LINK_EVENT_UNSUBSCRIBE) { - MIH_C_LINK_EVENT_LIST_T mih_unsubscribed_req_event_list; - MIH_C_LINK_EVENT_LIST_T saved_req_event_list; - - saved_req_event_list = ralpriv->mih_subscribe_req_event_list; - - ralpriv->mih_subscribe_req_event_list &= ~(msgP->primitive.RequestedLinkEventList & ralpriv->mih_supported_link_event_list); - mih_unsubscribed_req_event_list = ralpriv->mih_subscribe_req_event_list ^ saved_req_event_list; - - status = MIH_C_STATUS_SUCCESS; - - eRALlte_send_event_unsubscribe_confirm(&msgP->header.transaction_id, - &status, - &mih_unsubscribed_req_event_list); - } else { - eRALlte_send_event_unsubscribe_confirm(&msgP->header.transaction_id, - &status, - NULL); - } -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_thresholds.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_thresholds.c deleted file mode 100644 index dba7d98e9a..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/eRALlte_thresholds.c +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#include "eRALlte_thresholds.h" - -#include "eRALlte_mih_msg.h" - -/****************************************************************************/ -/******************* G L O C A L D E F I N I T I O N S *****************/ -/****************************************************************************/ - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -/**************************************************************************** - ** ** - ** Name: eRALlte_configure_thresholds_request() ** - ** ** - ** Description: Processes the Link_Configure_Thresholds.request message ** - ** and sends a Link_Configure_Thresholds.confirm message to ** - ** the MIHF. ** - ** ** - ** Inputs: msgP: Pointer to the received message ** - ** Others: ralpriv ** - ** ** - ** Outputs: None ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -void eRALlte_configure_thresholds_request(MIH_C_Message_Link_Configure_Thresholds_request_t* msgP) -{ - MIH_C_STATUS_T status = MIH_C_STATUS_REJECTED; - - /* Configure thresholds link command is not supported at the network side */ - DEBUG(" Configure thresholds request is not supported by the network\n"); - eRALlte_send_configure_thresholds_confirm(&msgP->header.transaction_id, - &status, NULL); -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_NAS.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_NAS.c deleted file mode 100755 index 6ea81a48f8..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_NAS.c +++ /dev/null @@ -1,468 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#define MRAL_MODULE -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -//#include <unistd.h> -//#include <sys/types.h> -#include <sys/socket.h> -//#include <sys/un.h> -//#include <sys/time.h> - -#include "mRALlte_mih_msg.h" -#include "mRALlte_variables.h" -#include "mRALlte_proto.h" -#include "MIH_C.h" -#include "mRALlte_mih_msg.h" - -#include "nasUE_config.h" -#include "nas_ue_netlink.h" - -extern char message[NAS_UE_NETL_MAXLEN]; -extern int sd_graal, s_nas; - -#define MSC_GEN_BUF_SIZE 1024 -static char msc_gen_buff[MSC_GEN_BUF_SIZE]; - -/*************************************************************************** - Reception side - ***************************************************************************/ -//--------------------------------------------------------------------------- -void print_state(uint8_t state) -{ - //--------------------------------------------------------------------------- - switch(state) { - case NAS_DISCONNECTED: - DEBUG("NAS_DISCONNECTED\n"); - return; - - case NAS_CONNECTED: - DEBUG("NAS_CONNECTED\n"); - return; - - default: - ERR(" Unknown state\n"); - } -} - -//--------------------------------------------------------------------------- -int IAL_decode_NAS_message(void) -{ - //--------------------------------------------------------------------------- - struct nas_ue_netl_reply *msgToRcve; - int done=0, n, i; - char *buffer; -#ifdef MSCGEN_PYTOOL - unsigned int buffer_index; -#endif - n = recv(s_nas, message, NAS_UE_NETL_MAXLEN, 0); - - if (n <= 0) { - if (n < 0) perror("RAL_process_DNAS_message : recv"); - - done = 1; - } - - if (!done) { - DEBUG(" "); - DEBUG("RAL_decode_NAS_message: primitive from NAS\n"); - msgToRcve = (struct nas_ue_netl_reply *) message; - - switch (msgToRcve->type) { - - case NAS_UE_MSG_CNX_ESTABLISH_REPLY: - NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_CNX_ESTABLISH_REPLY --->][%s]\n", getTimeStamp4Log(), g_link_id); - DEBUG("NAS_UE_MSG_CNX_ESTABLISH_REPLY received\n"); - ralpriv->pending_req_action = MIH_C_LINK_AC_TYPE_NONE; - ralpriv->state = DISCONNECTED; - - if (msgToRcve->ialNASPrimitive.cnx_est_rep.status==0) { - ERR(" Connexion establishment failure: %d\n",msgToRcve->ialNASPrimitive.cnx_est_rep.status); - done = 1; - ralpriv->pending_req_status = MIH_C_STATUS_SUCCESS; - ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_FAILURE; - //mRALu_send_link_switch_cnf(); - //mRALte_send_link_action_confirm(); - } else { - ralpriv->pending_req_status = MIH_C_STATUS_SUCCESS; - ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_SUCCESS; - ralpriv->pending_req_flag = 1; - DEBUG(" Connexion establishment pending: pending_req_flag %d\n\n",ralpriv->pending_req_flag); - } - - break; - - case NAS_UE_MSG_CNX_RELEASE_REPLY: - NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_CNX_RELEASE_REPLY --->][%s]\n", - getTimeStamp4Log(), - g_link_id); - DEBUG("NAS_UE_MSG_CNX_RELEASE_REPLY received\n"); - ralpriv->pending_req_action = MIH_C_LINK_AC_TYPE_NONE; - - if (msgToRcve->ialNASPrimitive.cnx_rel_rep.status>0) { - ERR(" Connexion release failure: %d", msgToRcve->ialNASPrimitive.cnx_rel_rep.status); - done = 1; - ralpriv->pending_req_status = MIH_C_STATUS_SUCCESS; - ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_FAILURE; - } else { - ralpriv->pending_req_status = MIH_C_STATUS_SUCCESS; - ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_SUCCESS; - ralpriv->pending_req_flag = 1; - DEBUG(" Connexion establishment pending: pending_req_flag %d\n\n",ralpriv->pending_req_flag); - } - - ralpriv->state = DISCONNECTED; - //mRALu_send_link_switch_cnf(); - //added - ralpriv->pending_req_flag = 0; - ralpriv->cell_id = CONF_UNKNOWN_CELL_ID; - break; - - case NAS_UE_MSG_CNX_LIST_REPLY: { - struct nas_ue_msg_cnx_list_reply *p; - NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_CNX_LIST_REPLY --->][%s]\n", - getTimeStamp4Log(), - g_link_id); - DEBUG("NAS_UE_MSG_CNX_LIST_REPLY received\n"); - p = &(msgToRcve->ialNASPrimitive.cnx_list_rep); - DEBUG(" CellId\tIID4\tIID6\t\t\tnum_rb\tnsclass\tState\n"); - - DEBUG(" %u\t%u\t", p->cellid, p->iid4); - - for (i=0; i<8; ++i) - DEBUG("%02x", *((uint8_t *)p->iid6+i)); - - DEBUG("\t%u\t%u\t", p->num_rb, p->nsclassifier); - print_state(p->state); - - ralpriv->nas_state = p->state ; - ralpriv->num_rb = p->num_rb; - ralpriv->cell_id = p->cellid ; - //IAL_return_NAS_StatAttach(); - } - break; - - case NAS_UE_MSG_RB_LIST_REPLY: { - struct nas_ue_msg_rb_list_reply *p; - NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_RB_LIST_REPLY --->][%s]\n", - getTimeStamp4Log(), - g_link_id); - DEBUG("NAS_UE_MSG_RB_LIST_REPLY received\n"); - p = &(msgToRcve->ialNASPrimitive.rb_list_rep); - ralpriv->num_rb = p->num_rb; - DEBUG("rab_id\t\tdscp\t\tQoS\t\tState\n"); - - for(i=0; i<p->num_rb; i++) { - DEBUG("%u\t\t%u\t\t%u\t\t", p->RBList[i].rbId, p->RBList[i].dscp, p->RBList[i].QoSclass); - print_state(p->RBList[i].state); - ralpriv->rbId[i]= p->RBList[i].rbId; - ralpriv->QoSclass[i] = p->RBList[i].QoSclass; - ralpriv->dscp[i] = p->RBList[i].dscp; - } - } - //IAL_return_NAS_StatRB(); - break; - - case NAS_UE_MSG_MEAS_REPLY: { - struct nas_ue_msg_measure_reply *p; - DEBUG("NAS_UE_MSG_MEASUREMENT_REPLY received\n"); - p = &(msgToRcve->ialNASPrimitive.meas_rep); -#ifdef DEBUG_MRALU_MEASURES - DEBUG("Measurement Report - Number of cells %d - Current cell %d\n", p->num_cells, ralpriv->cell_id); - DEBUG("Cell_id\tMeasure\tProvider_id\n"); -#endif - - for (i=0; i<p->num_cells; i++) { -#ifdef DEBUG_MRALU_MEASURES - DEBUG(" %d\t%d\t%d\n",p-> measures[i].cell_id,p-> measures[i].level,p-> measures[i].provider_id); -#endif - ralpriv->meas_cell_id[i] = p-> measures[i].cell_id; - IAL_integrate_measure(p-> measures[i].level, i); - ralpriv->provider_id[i] = p-> measures[i].provider_id; - } - -#ifdef MSCGEN_PYTOOL - memset(msc_gen_buff, 0, MSC_GEN_BUF_SIZE); - buffer_index = 0; - - for (i=0; i<p->num_cells; i++) { - buffer_index += sprintf(&msc_gen_buff[buffer_index], "\\nCell Id %d Level %d Provider %d", - p-> measures[i].cell_id, p-> measures[i].level, p-> measures[i].provider_id); - ralpriv->meas_cell_id[i] = p-> measures[i].cell_id; - } - - NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_MEASUREMENT_REPLY%s --->][%s]\n", - getTimeStamp4Log(), - msc_gen_buff, - g_link_id); -#endif - //Temp -#ifdef RAL_DUMMY - ralpriv->num_measures = p->num_cells; //TEMP- To be activated later -#endif - //ralpriv->meas_cell_id[0] = ralpriv->cell_id; - } - break; - - case NAS_UE_MSG_IMEI_REPLY: - DEBUG("NAS_UE_MSG_IMEI_REPLY received\n"); - DEBUG("IMEI value received= %d %d\n", msgToRcve->ialNASPrimitive.l2id_rep.l2id[0], msgToRcve->ialNASPrimitive.l2id_rep.l2id[1]); - //store the received value, to be used later - ralpriv->ipv6_l2id[0] = msgToRcve->ialNASPrimitive.l2id_rep.l2id[0]; - ralpriv->ipv6_l2id[1] = msgToRcve->ialNASPrimitive.l2id_rep.l2id[1]; - buffer = (char *)(&ralpriv->ipv6_l2id[0]); - DEBUG ("IMEI value: = "); - - for (i = 0; i < 8; i++) { - DEBUG ("-%hhx-", (unsigned char) buffer[i]); - } - - DEBUG ("\n"); -#ifdef MSCGEN_PYTOOL - memset(msc_gen_buff, 0, MSC_GEN_BUF_SIZE); - buffer_index = 0; - buffer_index = sprintf(&msc_gen_buff[buffer_index], "\\nIMEI:%hhx-%hhx-%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", - (unsigned char) buffer[0],(unsigned char) buffer[1], - (unsigned char) buffer[2],(unsigned char) buffer[3], - (unsigned char) buffer[4],(unsigned char) buffer[5], - (unsigned char) buffer[6],(unsigned char) buffer[7]); - NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_IMEI_REPLY --->][%s]\n", - getTimeStamp4Log(), - g_link_id); -#endif - break; - - default: - ERR("IAL_decode_NAS_message : invalid message Type %d\n",msgToRcve->type); - done = 1; - } - } - - return done; -} - - -/*************************************************************************** - Transmission side - ***************************************************************************/ - -//--------------------------------------------------------------------------- -int IAL_process_DNAS_message(int ioctl_obj, int ioctl_cmd, int ioctl_cellid) -{ - //--------------------------------------------------------------------------- - struct nas_ue_netl_request *msgToSend; - int rc; - - - msgToSend = (struct nas_ue_netl_request *) message; - memset(message,0,NAS_UE_NETL_MAXLEN); - - NOTICE(" \n"); - - switch (ioctl_obj) { - case IO_OBJ_CNX: - switch (ioctl_cmd) { - /***/ - case IO_CMD_ADD: { - NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_CNX_ESTABLISH_REQUEST --->][nas]\n", - getTimeStamp4Log(), - g_link_id); - msgToSend->type=NAS_UE_MSG_CNX_ESTABLISH_REQUEST; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request); - msgToSend->ialNASPrimitive.cnx_req.cellid = ioctl_cellid; - ralpriv->cell_id = ioctl_cellid; - // - DEBUG("ioctl : Connection establishment requested\n"); - rc = 0; - } - break; - - /***/ - case IO_CMD_DEL: { - - NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_CNX_RELEASE_REQUEST --->][nas]\n", - getTimeStamp4Log(), - g_link_id); - msgToSend->type=NAS_UE_MSG_CNX_RELEASE_REQUEST; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request); - // - DEBUG("ioctl : Connexion release requested\n"); - rc = 0; - } - break; - - /***/ - case IO_CMD_LIST: { - NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_CNX_LIST_REQUEST --->][nas]\n", - getTimeStamp4Log(), - g_link_id); - msgToSend->type=NAS_UE_MSG_CNX_LIST_REQUEST; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request); - // - DEBUG("ioctl : Connexion list requested\n"); - rc = 0; - } - break; - - /***/ - default: - ERR("IAL_process_DNAS_message : invalid ioctl command %d\n",ioctl_cmd); - rc= -1; - } //end switch ioctl_cmd - - break; - - /***************************/ - case IO_OBJ_RB: - switch (ioctl_cmd) { - /***/ - case IO_CMD_LIST: { - NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_RB_LIST_REQUEST --->][nas]\n", - getTimeStamp4Log(), - g_link_id); - msgToSend->type=NAS_UE_MSG_RB_LIST_REQUEST; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request); - // - DEBUG("ioctl : Radio bearer list requested\n"); - rc = 0; - } - break; - - /***/ - default: - ERR("IAL_process_DNAS_message : invalid ioctl command %d\n",ioctl_cmd); - rc= -1; - } //end switch ioctl_cmd - - break; - - /***************************/ - case IO_OBJ_MEAS: - // - { - msgToSend->type=NAS_UE_MSG_MEAS_REQUEST; - NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_MEAS_REQUEST --->][nas]\n", - getTimeStamp4Log(), - g_link_id); - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request); - // - DEBUG("ioctl : Measurement requested\n"); - rc = 0; - } - break; - - /***************************/ - case IO_OBJ_IMEI: { - NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_IMEI_REQUEST --->][nas]\n", - getTimeStamp4Log(), - g_link_id); - msgToSend->type=NAS_UE_MSG_IMEI_REQUEST; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request); - // - DEBUG("ioctl : L2Id (IMEI) requested\n"); - rc = 0; - } - break; - - /***************************/ - default: - ERR("IAL_process_DNAS_message : invalid ioctl object %d\n",ioctl_obj); - rc= -1; - } //end switch ioctl_obj - - if (!rc) { - if (send(s_nas, message,msgToSend->length, 0) < 0) { - perror("IAL_process_DNAS_message : send"); - rc= -1; - } - - DEBUG ("message sent to NAS %d\n",msgToSend->length); - } - - return rc; -} - - - - -/*************************************************************************** - Tool functions - ***************************************************************************/ - - - -//--------------------------------------------------------------------------- -// Convert the IMEI to iid -void TQAL_NAS_imei2iid(uint8_t *imei, uint8_t *iid) -{ - //--------------------------------------------------------------------------- - // Start debug information - - if (!imei ||! iid ) { - ERR("TQAL_NAS_imei2iid - input parameter is NULL \n"); - return; - } - - // End debug information - memset(iid, 0, 8); - iid[0] = 16*imei[0]+imei[1]; - iid[1] = 16*imei[2]+imei[3]; - iid[2] = 16*imei[4]+imei[5]; - iid[3] = 16*imei[6]+imei[7]; - iid[4] = 16*imei[8]+imei[9]; - iid[5] = 16*imei[10]+imei[11]; - iid[6] = 16*imei[12]+imei[13]; - iid[7] = 16*imei[14]+imei[15]; -} - - -//--------------------------------------------------------------------------- -// Convert the IMEI to iid -void TQAL_NAS_imei2iid2(uint8_t *imei, uint32_t *iid) -{ - //--------------------------------------------------------------------------- - // Start debug information - - if (!imei ||! iid ) { - ERR("TQAL_NAS_imei2iid - input parameter is NULL \n"); - return; - } - - // End debug information - // memset(iid, 0, 8); - iid[0] = imei[0]+256 *(imei[1]+256*(imei[2]+256*(imei[3]))); - iid[1] = imei[4]+256 *(imei[5]+256*(imei[6]+256*(imei[7]))); -} - - - - - diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_action.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_action.c deleted file mode 100755 index f35fa91f29..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_action.c +++ /dev/null @@ -1,229 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -#define MRAL_MODULE -#define MRALLTE_ACTION_C -#include <assert.h> -#include "mRALlte_action.h" -#include "mRALlte_variables.h" -#include "nas_ue_ioctl.h" -#include "mRALlte_proto.h" - -//----------------------------------------------------------------------------- -void mRALlte_action_request(MIH_C_Message_Link_Action_request_t* messageP) -{ - //----------------------------------------------------------------------------- - MIH_C_STATUS_T status; - LIST(MIH_C_LINK_SCAN_RSP, scan_response_set); - MIH_C_LINK_AC_RESULT_T link_action_result; - MIH_C_TRANSACTION_ID_T transaction_id; - unsigned int scan_index; - - - memcpy(&g_link_action, &messageP->primitive.LinkAction, sizeof(MIH_C_LINK_ACTION_T)); - - status = MIH_C_STATUS_SUCCESS; - link_action_result = MIH_C_LINK_AC_RESULT_SUCCESS; - scan_response_set_list.length = 0; - - if ( messageP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_LINK_SCAN) { - for (scan_index = 0; scan_index < ralpriv->num_measures; scan_index++) { - //MIH_C_LINK_ADDR_T - scan_response_set_list.val[scan_index].link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_set(&scan_response_set_list.val[scan_index].link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP, strlen(DEFAULT_ADDRESS_3GPP)); - // MIH_C_NETWORK_ID_T - MIH_C_NETWORK_ID_set(&scan_response_set_list.val[scan_index].network_id, (u_int8_t *)PREDEFINED_MIH_NETWORK_ID, strlen(PREDEFINED_MIH_NETWORK_ID)); - // MIH_C_SIG_STRENGTH_T - - scan_response_set_list.val[scan_index].sig_strength.choice = MIH_C_SIG_STRENGTH_CHOICE_PERCENTAGE; - scan_response_set_list.val[scan_index].sig_strength._union.percentage = ralpriv->integrated_meas_level[scan_index]; - scan_response_set_list.length += 1; - } - - transaction_id = messageP->header.transaction_id; - - mRALlte_send_link_action_confirm(&transaction_id, - &status, - &scan_response_set_list, - &link_action_result); - - } - - if ( messageP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_LINK_RES_RETAIN) { - // TO DO - } - - if ( messageP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_DATA_FWD_REQ) { - // TO DO - } - - // do not make actions if SCAN required - if (( messageP->primitive.LinkAction.link_ac_attr & MIH_C_BIT_LINK_AC_ATTR_LINK_SCAN) == 0) { - switch (messageP->primitive.LinkAction.link_ac_type) { - case MIH_C_LINK_AC_TYPE_NONE: - DEBUG("%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_NONE: NO ACTION\n", __FUNCTION__); - break; - - case MIH_C_LINK_AC_TYPE_LINK_DISCONNECT: - DEBUG("%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_DISCONNECT: NO ACTION\n", __FUNCTION__); - - if (ralpriv->mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_DISCONNECT) { - } else { - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - ralpriv->pending_req_status = 0; - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - - break; - - case MIH_C_LINK_AC_TYPE_LINK_LOW_POWER: - DEBUG("%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_LOW_POWER\n", __FUNCTION__); - - if (ralpriv->mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_LOW_POWER) { - } else { - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - ralpriv->pending_req_status = 0; - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - - break; - - case MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN: - DEBUG("%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN\n", __FUNCTION__); - - if (ralpriv->mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN) { - if ( ralpriv->pending_req_action & MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN ) { - if (ralpriv->state == DISCONNECTED) { - DEBUG("Deactivation requested, but interface already inactive ==> NO OP\n"); - ralpriv->pending_req_status = 0; - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } else { - ralpriv->pending_req_action = ralpriv->pending_req_action | MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN; - ralpriv->pending_req_status = 0; - ralpriv->pending_req_transaction_id = messageP->header.transaction_id; - DEBUG("Deactivation requested to NAS interface\n"); - IAL_process_DNAS_message(IO_OBJ_CNX, IO_CMD_DEL, ralpriv->cell_id); - //Send immediatly a confirm, otherwise it will arrive to late and MIH-F will report a failure to the MIH-USER - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, NULL, &link_action_result); - } - } else { - ralpriv->pending_req_action |= MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN; - ralpriv->pending_req_status = 0; - ralpriv->pending_req_transaction_id = messageP->header.transaction_id; - DEBUG("Deactivation requested to NAS interface\n"); - IAL_process_DNAS_message(IO_OBJ_CNX, IO_CMD_DEL, ralpriv->cell_id); - //Send immediatly a confirm, otherwise it will arrive to late and MIH-F will report a failure to the MIH-USER - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, NULL, &link_action_result); - } - } else { - DEBUG ("[mRAL]: command POWER DOWN not available \n\n"); - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - ralpriv->pending_req_status = 0; - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, NULL, &link_action_result); - } - - break; - - case MIH_C_LINK_AC_TYPE_LINK_POWER_UP: - DEBUG("%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_POWER_UP\n", __FUNCTION__); - - if (ralpriv->mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_POWER_UP) { - // Activation requested - check it is not already active - if(ralpriv->pending_req_action & MIH_C_LINK_AC_TYPE_LINK_POWER_UP) { - if (ralpriv->state == CONNECTED) { - DEBUG("Activation requested, but interface already active ==> NO OP\n"); - ralpriv->pending_req_status = 0; - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } else { - ralpriv->pending_req_action = ralpriv->pending_req_action | MIH_C_LINK_AC_TYPE_LINK_POWER_UP; - ralpriv->pending_req_status = 0; - ralpriv->pending_req_transaction_id = messageP->header.transaction_id; - DEBUG("Activation requested to NAS interface\n"); - IAL_process_DNAS_message(IO_OBJ_CNX, IO_CMD_ADD, ralpriv->cell_id); - } - } else { - ralpriv->pending_req_action |= MIH_C_LINK_AC_TYPE_LINK_POWER_UP; - ralpriv->pending_req_status = 0; - ralpriv->pending_req_transaction_id = messageP->header.transaction_id; - DEBUG("Activation requested to NAS interface\n"); - IAL_process_DNAS_message(IO_OBJ_CNX, IO_CMD_ADD, ralpriv->cell_id); - } - } else { - DEBUG ("[mRAL]: command POWER UP not available \n\n"); - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - ralpriv->pending_req_status = 0; - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - - break; - - case MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR: - DEBUG("%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR: NO ACTION\n", __FUNCTION__); - - if (ralpriv->mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR) { - } else { - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - ralpriv->pending_req_status = 0; - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - - break; - - case MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES: - DEBUG("%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES: NO ACTION\n", __FUNCTION__); - - if (ralpriv->mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES) { - } else { - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - ralpriv->pending_req_status = 0; - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - - break; - - case MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES: - DEBUG("%s ACTION REQUESTED: MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES: NO ACTION\n", __FUNCTION__); - - if (ralpriv->mih_supported_action_list & MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES) { - } else { - link_action_result = MIH_C_LINK_AC_RESULT_INCAPABLE; - ralpriv->pending_req_status = 0; - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - - break; - - default: - ERR("%s Invalid LinkAction.link_ac_type in MIH_C_Message_Link_Action_request\n", __FUNCTION__); - status = MIH_C_STATUS_UNSPECIFIED_FAILURE; - mRALlte_send_link_action_confirm(&messageP->header.transaction_id, &status, &scan_response_set_list, &link_action_result); - } - } -} - diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_get.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_get.c deleted file mode 100755 index 48d41eb692..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_get.c +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#define MRAL_MODULE -#define MRALLTE_GET_C -#include "mRALlte_get.h" - -//----------------------------------------------------------------------------- -void MIH_C_3GPP_ADDR_load_3gpp_str_address(MIH_C_3GPP_ADDR_T* _3gpp_addrP, u_int8_t* strP) -//----------------------------------------------------------------------------- -{ - int i, l; - u_int8_t val_temp; - unsigned char address_3gpp[32]; - unsigned char buf[3]; - u_int8_t _3gpp_byte_address[8]; - - strcpy((char *)address_3gpp, (char *)strP); - - for(l=0; l<8; l++) { - i=l*2; - buf[0]= address_3gpp[i]; - buf[1]= address_3gpp[i+1]; - buf[2]= '\0'; - //sscanf((const char *)buf,"%02x", &val_temp); - sscanf((const char *)buf,"%hhx", &val_temp); - _3gpp_byte_address[l] = val_temp; - } - - MIH_C_3GPP_ADDR_set(_3gpp_addrP, _3gpp_byte_address, 8); -} \ No newline at end of file diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_main.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_main.c deleted file mode 100755 index 233aacb43b..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_main.c +++ /dev/null @@ -1,447 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#define MRAL_MODULE -#define MRALLTE_MAIN_C -//----------------------------------------------------------------------------- -#include "mRALlte_main.h" -#include "mRALlte_constants.h" -#include "mRALlte_variables.h" -#include "mRALlte_proto.h" -#include "mRALlte_mih_msg.h" -#include "nas_ue_netlink.h" -#include "nasUE_config.h" -//----------------------------------------------------------------------------- -#include "MIH_C.h" -//----------------------------------------------------------------------------- - -#define NAS_UE_NETL_MAXLEN 500 -// TO DO -#ifndef SVN_REV -#define SVN_REV "0.1" -#endif -// Global variables -int netl_s, s_nas; -struct sockaddr_un ralu_socket; -int wait_start_mihf; -int listen_mih; -struct ral_lte_priv rl_priv; -struct ral_lte_priv *ralpriv; - - -char message[NAS_UE_NETL_MAXLEN]; -static int g_log_output; -//----------------------------------------------------------------------------- -static void arg_usage(char *exec_nameP) -{ - //----------------------------------------------------------------------------- - fprintf(stderr, - "Usage: %s [options]\nOptions:\n" - " -V, --version Display version information\n" - " -?, -h, --help Display this help text\n" - " -P <number>, --ral-listening-port Listening port for incoming MIH-F messages\n" - " -I <string>, --ral-ip-address Binding IP(v4 or v6) address for RAL\n" - " -p <number>, --mihf-remote-port MIH-F remote port\n" - " -i <string>, --mihf-ip-address MIH-F IP(v4 or v6) address\n" - " -c, --output-to-console All stream outputs are redirected to console\n" - " -f, --output-to-syslog All stream outputs are redirected to file\n" - " -s, --output-to-syslog All stream outputs are redirected to syslog\n", - exec_nameP); -} - -//--------------------------------------------------------------------------- -int parse_opts(int argc, char *argv[]) -{ - //--------------------------------------------------------------------------- - static struct option long_opts[] = { - {"version", 0, 0, 'V'}, - {"help", 0, 0, 'h'}, - {"ral-listening-port", optional_argument, 0, 'P'}, - {"ral-ip-address", optional_argument, 0, 'I'}, - {"mihf-remote-port", optional_argument, 0, 'p'}, - {"mihf-ip-address", optional_argument, 0, 'i'}, - {"link.id", optional_argument, 0, 'l'}, - {"mihf.id", optional_argument, 0, 'm'}, - {"output-to-console", 0, 0, 'c'}, - {"output-to-file", 0, 0, 'f'}, - {"output-to-syslog", 0, 0, 's'}, - {0, 0, 0, 0} - }; - - /* parse all other cmd line parameters than -c */ - while (1) { - int idx, c; - c = getopt_long(argc, argv, "PIpil:Vh?cfs", long_opts, &idx); - - if (c == -1) break; - - switch (c) { - case 'V': - fprintf(stderr, "SVN MODULE VERSION: %s\n", SVN_REV); - return -1; - - case '?': - case 'h': - arg_usage(basename(argv[0])); - return -1; - - case 'i': - fprintf(stderr, "Option mihf-ip-address:\t%s\n", optarg); - g_mihf_ip_address = optarg; - break; - - case 'p': - fprintf(stderr, "Option mihf-remote-port:\t%s\n", optarg); - g_mihf_remote_port = optarg; - break; - - case 'P': - fprintf(stderr, "Option ral-listening-port:\t%s\n", optarg); - g_ral_listening_port_for_mihf = optarg; - break; - - case 'I': - fprintf(stderr, "Option ral-ip-address:\t%s\n", optarg); - g_ral_ip_address = optarg; - break; - - case 'l': - fprintf(stderr, "Option link.id:\t%s\n", optarg); - g_link_id = optarg; - break; - - case 'm': - fprintf(stderr, "Option mihf.id:\t%s\n", optarg); - g_mihf_id = optarg; - break; - - case 'c': - fprintf(stderr, "Option output-to-console\n"); - g_log_output = LOG_TO_CONSOLE; - break; - - case 'f': - fprintf(stderr, "Option output-to-file\n"); - g_log_output = LOG_TO_FILE; - break; - - case 's': - fprintf(stderr, "Option output-to-syslog\n"); - g_log_output = LOG_TO_SYSTEM; - break; - - default: - WARNING("UNKNOWN OPTION\n"); - break; - }; - } - - return 0; -} -//--------------------------------------------------------------------------- -void IAL_D_Netlink_socket_init(void) -{ - //--------------------------------------------------------------------------- - int len; - struct sockaddr_un local; - - if ((netl_s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - perror("IAL_D_Netlink_socket_init : socket command failed, err %d\n"); - exit(1); - } - - local.sun_family = AF_UNIX; - strcpy(local.sun_path, SOCK_NAS_PATH); - unlink(local.sun_path); - len = strlen(local.sun_path) + sizeof(local.sun_family); - - if (bind(netl_s, (struct sockaddr *)&local, len) == -1) { - perror("IAL_D_Netlink_socket_init : bind command failed, \n"); - exit(1); - } - - if (listen(netl_s, 1) == -1) { - perror("IAL_D_Netlink_socket_init : listen command failed, \n"); - exit(1); - } -} -//--------------------------------------------------------------------------- -void mRALlte_get_IPv6_addr(void) -{ - //--------------------------------------------------------------------------- -#define IPV6_ADDR_LINKLOCAL 0x0020U - -#ifdef RAL_DUMMY - char * eth0_name="eth0";/* interface name */ -#endif -#ifdef RAL_REALTIME - char * graal0_name="graal0";/* interface name */ -#endif - - FILE *f; - char devname[20]; - int plen, scope, dad_status, if_idx; - char addr6p[8][5]; - int intf_found = 0; - char my_addr[16]; - char temp_addr[32]; - int i, j; - - if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) { - while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], - addr6p[4], addr6p[5], addr6p[6], addr6p[7], - &if_idx, &plen, &scope, &dad_status, devname) != EOF) { -#ifdef RAL_DUMMY - - if (!strcmp(devname, eth0_name)) { -#endif -#ifdef RAL_REALTIME - - if (!strcmp(devname, graal0_name)) { -#endif - intf_found = 1; - - // retrieve numerical value - if ((scope ==0)||(scope== IPV6_ADDR_LINKLOCAL)) { - DEBUG(" adresse %s:%s:%s:%s:%s:%s:%s:%s", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], - addr6p[4], addr6p[5], addr6p[6], addr6p[7]); - DEBUG(" Scope:"); - - switch (scope) { - case 0: - DEBUG("Global"); - break; - - case IPV6_ADDR_LINKLOCAL: - DEBUG("Link"); - break; - - default: - DEBUG("Unknown"); - } - - DEBUG("\n Numerical value: "); - - for (i = 0; i < 8; i++) { - for (j=0; j<4; j++) { - addr6p[i][j]= toupper(addr6p[i][j]); - - if ((addr6p[i][j] >= 'A') && (addr6p[i][j] <= 'F')) { - temp_addr[(4*i)+j] =(unsigned short int)(addr6p[i][j]-'A')+10; - } else if ((addr6p[i][j] >= '0') && (addr6p[i][j] <= '9')) { - temp_addr[(4*i)+j] =(unsigned short int)(addr6p[i][j]-'0'); - } - } - - my_addr[2*i]= (16*temp_addr[(4*i)])+temp_addr[(4*i)+1]; - my_addr[(2*i)+1]= (16*temp_addr[(4*i)+2])+temp_addr[(4*i)+3]; - - } - - for (i=0; i<16; i++) { - DEBUG("-%hhx-",my_addr[i]); - } - - DEBUG("\n\n"); - } - } - } - - fclose(f); - - if (!intf_found) { - ERR("interface not found\n\n"); - } - } - } - - //--------------------------------------------------------------------------- - int inits(int argc, char *argv[]) { - //--------------------------------------------------------------------------- - MIH_C_TRANSACTION_ID_T transaction_id; - unsigned int t; - struct sockaddr_un nas_socket; - - ralpriv = &rl_priv; - memset(ralpriv, 0, sizeof(struct ral_lte_priv)); - - memset(g_msg_codec_recv_buffer, 0, MSG_CODEC_RECV_BUFFER_SIZE); - // Initialize defaults - g_ral_ip_address = DEFAULT_IP_ADDRESS_RAL; - g_ral_listening_port_for_mihf = DEFAULT_LOCAL_PORT_RAL; - g_mihf_remote_port = DEFAULT_REMOTE_PORT_MIHF; - g_mihf_ip_address = DEFAULT_IP_ADDRESS_MIHF; - g_link_id = DEFAULT_LINK_ID; - g_mihf_id = DEFAULT_MIHF_ID; - g_sockd_mihf = -1; - g_log_output = LOG_TO_CONSOLE; - - MIH_C_init(g_log_output); - - if (parse_opts( argc, argv) < 0) { - exit(0); - } - - - if (mRALlte_mihf_connect() < 0 ) { - ERR("Could not connect to MIH-F...exiting\n"); - exit(-1); - } - - DEBUG("MT-MIHF socket initialized.\n\n"); - - // excluded MIH_C_LINK_AC_TYPE_NONE - // excluded MIH_C_LINK_AC_TYPE_LINK_LOW_POWER - // excluded MIH_C_LINK_AC_TYPE_NONE - ralpriv->mih_supported_action_list = MIH_C_LINK_AC_TYPE_LINK_DISCONNECT | - MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN | - MIH_C_LINK_AC_TYPE_LINK_POWER_UP | - MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR | - MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES | - MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES; - - - - ralpriv->mih_supported_link_event_list = MIH_C_BIT_LINK_DETECTED | - MIH_C_BIT_LINK_UP | - MIH_C_BIT_LINK_DOWN | - MIH_C_BIT_LINK_PARAMETERS_REPORT | - MIH_C_BIT_LINK_GOING_DOWN | - MIH_C_BIT_LINK_HANDOVER_IMMINENT | - MIH_C_BIT_LINK_HANDOVER_COMPLETE | - MIH_C_BIT_LINK_PDU_TRANSMIT_STATUS; - - ralpriv->mih_supported_link_command_list = MIH_C_BIT_LINK_EVENT_SUBSCRIBE | MIH_C_BIT_LINK_EVENT_UNSUBSCRIBE | \ - MIH_C_BIT_LINK_GET_PARAMETERS | MIH_C_BIT_LINK_CONFIGURE_THRESHOLDS | \ - MIH_C_BIT_LINK_ACTION; - - ralpriv->link_to_be_detected = MIH_C_BOOLEAN_TRUE; - - NOTICE("[MSC_NEW][%s][MIH-F=%s]\n", getTimeStamp4Log(), g_mihf_id); - NOTICE("[MSC_NEW][%s][RAL=%s]\n", getTimeStamp4Log(), g_link_id); - NOTICE("[MSC_NEW][%s][NAS=%s]\n", getTimeStamp4Log(), "nas"); - - IAL_D_Netlink_socket_init(); - DEBUG("Waiting for a connection from NAS Driver ...\n"); - t = sizeof(nas_socket); - - if ((s_nas = accept(netl_s, (struct sockaddr *)&nas_socket, &t)) == -1) { - perror("main - s_nas - accept "); - exit(1); - } - - DEBUG("NAS Driver Connected.\n\n"); - - - // get interface ipv6 address - mRALlte_get_IPv6_addr(); - // get L2 identifier - IAL_process_DNAS_message(IO_OBJ_IMEI, IO_CMD_ADD, 0); - - IAL_decode_NAS_message(); - - // Initialize measurements - IAL_NAS_measures_init(); - ralpriv->state = DISCONNECTED; - - IAL_process_DNAS_message(IO_OBJ_MEAS, IO_CMD_LIST, ralpriv->cell_id); - IAL_decode_NAS_message(); - - - transaction_id = (MIH_C_TRANSACTION_ID_T)0; - mRALlte_send_link_register_indication(&transaction_id); - - return 0; - } - - //--------------------------------------------------------------------------- - int main(int argc, char *argv[]) { - //--------------------------------------------------------------------------- - int rc, done; - int meas_polling_counter; - fd_set readfds; - struct timeval tv; - - inits(argc, argv); - - done = 0; - ralpriv->pending_req_flag = 0; - meas_polling_counter = 1; - - do { - // Create fd_set and wait for input; - FD_ZERO(&readfds); - FD_SET(g_sockd_mihf, &readfds); - FD_SET (s_nas, &readfds); - tv.tv_sec = MIH_C_RADIO_POLLING_INTERVAL_SECONDS; - tv.tv_usec = MIH_C_RADIO_POLLING_INTERVAL_MICRO_SECONDS; - - rc= select(FD_SETSIZE, &readfds, NULL, NULL, &tv); - - if(rc == -1) { - perror("select"); - done = 1; - } - - //something received! - if(rc >= 0) { - if(FD_ISSET(g_sockd_mihf, &readfds)) { - done=mRALlte_mih_link_process_message(); - } /*else { // tick - - mRALlte_mih_fsm(NULL, 0); - }*/ - - if (FD_ISSET(s_nas,&readfds)) { - //printf("\n something received s_nas\n"); - done = IAL_decode_NAS_message(); - } - - //get measures from NAS - timer = 21x100ms -- impair - // if (meas_polling_counter ++ == 51){ - if (meas_polling_counter ++ == 51) { - IAL_NAS_measures_update(meas_polling_counter); - rallte_NAS_measures_polling(); - meas_polling_counter =1; - } - - if (ralpriv->pending_req_flag > 0) { //wait until next time - ralpriv->pending_req_flag ++; - rallte_verifyPendingConnection(); - } - - } - } while(!done); - - close(g_sockd_mihf); - close(netl_s); - MIH_C_exit(); - return 0; - } diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_mih_msg.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_mih_msg.c deleted file mode 100755 index 27e3cca97f..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_mih_msg.c +++ /dev/null @@ -1,1434 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#define MRAL_MODULE -#define MRALLTE_MIH_MSG_C -//----------------------------------------------------------------------------- -#include "mRALlte_mih_msg.h" -#include "mRALlte_subscribe.h" -#include "mRALlte_variables.h" -#include "mRALlte_parameters.h" -#include "mRALlte_thresholds.h" -#include "mRALlte_action.h" -//----------------------------------------------------------------------------- - -static char g_msg_codec_tmp_print_buffer[8192]; -#ifdef MSCGEN_PYTOOL -#define MSC_GEN_BUF_SIZE 1024 -// global instead of poisonning the stack -static char g_msc_gen_buf[MSC_GEN_BUF_SIZE]; -static unsigned int g_msc_gen_buffer_index; -#endif - - -//----------------------------------------------------------------------------- -int mRALlte_send_to_mih(u_int8_t *bufferP, size_t lenP) -{ - //----------------------------------------------------------------------------- - int result; - mRALlte_print_buffer((char*)bufferP, lenP); - result = send(g_sockd_mihf, (const void *)bufferP, lenP, 0); - - if (result != lenP) { - ERR("send_to_mih %d bytes failed, returned %d: %s\n", lenP, result, strerror(errno)); - } - - return result; -} -//----------------------------------------------------------------------------- -// Print the content of a buffer in hexadecimal -void mRALlte_print_buffer(char * bufferP, int lengthP) -{ - //----------------------------------------------------------------------------- - char c; - unsigned int buffer_index = 0; - unsigned int index; - unsigned int octet_index = 0; - unsigned long char_index = 0; - - if (bufferP == NULL) { - return; - } - - - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], "\n------+-------------------------------------------------+------------------+\n"); - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], " | 0 1 2 3 4 5 6 7 8 9 a b c d e f | 0123456789abcdef |\n"); - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], "------+-------------------------------------------------+------------------+\n"); - - for (octet_index = 0; octet_index < lengthP; octet_index++) { - if ((octet_index % 16) == 0) { - if (octet_index != 0) { - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], " | "); - - for (char_index = octet_index - 16; char_index < octet_index; char_index++) { - c = (char) bufferP[char_index] & 0177; - - if (iscntrl(c) || isspace(c)) { - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], " "); - } else { - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], "%c", c); - } - } - - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], " |\n"); - } - - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], " %04d |", octet_index); - } - - /* - * Print every single octet in hexadecimal form - */ - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], " %02x", (u_int8_t)(bufferP[octet_index] & 0x00FF)); - /* - * Align newline and pipes according to the octets in groups of 2 - */ - } - - /* - * Append enough spaces and put final pipe - */ - if ((lengthP % 16) > 0) { - for (index = (octet_index % 16); index < 16; ++index) { - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], " "); - } - } - - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], " | "); - - for (char_index = (octet_index / 16) * 16; char_index < octet_index; char_index++) { - c = (char) bufferP[char_index] & 0177; - - if (iscntrl(c) || isspace(c)) { - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], " "); - } else { - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], "%c", c); - } - } - - if ((lengthP % 16) > 0) { - for (index = (octet_index % 16); index < 16; ++index) { - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], " "); - } - } - - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], " |\n"); - buffer_index += sprintf(&g_msg_codec_tmp_print_buffer[buffer_index], "------+-------------------------------------------------+------------------+\n"); - DEBUG(g_msg_codec_tmp_print_buffer); -} -//--------------------------------------------------------------------------- -int mRALlte_mihf_connect(void) -{ - //--------------------------------------------------------------------------- - struct addrinfo hints; - struct addrinfo *result, *rp; - int s, on; - struct sockaddr_in *addr = NULL; - struct sockaddr_in6 *addr6 = NULL; - unsigned char buf[sizeof(struct sockaddr_in6)]; - - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ - hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ - hints.ai_flags = 0; - hints.ai_protocol = 0; /* Any protocol */ - - s = getaddrinfo(g_mihf_ip_address, g_mihf_remote_port, &hints, &result); - - if (s != 0) { - ERR(" getaddrinfo: %s\n", gai_strerror(s)); - freeaddrinfo(result); - return -1; - } - - /* getaddrinfo() returns a list of address structures. - Try each address until we successfully connect(2). - If socket(2) (or connect(2)) fails, we (close the socket - and) try the next address. */ - - for (rp = result; rp != NULL; rp = rp->ai_next) { - g_sockd_mihf = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - - if (g_sockd_mihf == -1) - continue; - - on = 1; - setsockopt( g_sockd_mihf, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - - if(rp->ai_family == AF_INET) { - DEBUG(" %s is an ipv4 address\n",g_mihf_ip_address); - addr = (struct sockaddr_in *)(&buf[0]); - addr->sin_port = htons(atoi(g_ral_listening_port_for_mihf)); - addr->sin_family = AF_INET; - s = inet_pton(AF_INET, g_ral_ip_address, &addr->sin_addr); - - if (s <= 0) { - if (s == 0) { - ERR(" IP RAL address should be a IPv4 ADDR - But found not in presentation format : %s\n", g_ral_ip_address); - } else { - ERR(" %s - inet_pton(RAL IPv4 ADDR %s): %s\n", __FUNCTION__, g_ral_ip_address, strerror(s)); - } - - return -1; - } - - s = bind(g_sockd_mihf, (const struct sockaddr *)addr, sizeof(struct sockaddr_in)); - - if (s == -1) { - ERR(" RAL IPv4 Address Bind: %s\n", strerror(errno)); - return -1; - } - - // sockd_mihf is of type SOCK_DGRAM, rp->ai_addr is the address to which datagrams are sent by default - if (connect(g_sockd_mihf, rp->ai_addr, rp->ai_addrlen) != -1) { - NOTICE(" RAL is now UDP-CONNECTED to MIH-F\n"); - freeaddrinfo(result); - return 0; - } else { - close(g_sockd_mihf); - } - } else if (rp->ai_family == AF_INET6) { - DEBUG(" %s is an ipv6 address\n",g_mihf_ip_address); - addr6 = (struct sockaddr_in6 *)(&buf[0]); - addr6->sin6_port = htons(atoi(g_ral_listening_port_for_mihf)); - addr6->sin6_family = AF_INET6; - s = inet_pton(AF_INET, g_ral_ip_address, &addr6->sin6_addr); - - if (s <= 0) { - if (s == 0) { - ERR(" IP RAL address should be a IPv6 ADDR, But found not in presentation format : %s\n", g_ral_ip_address); - } else { - ERR(" %s - inet_pton(RAL IPv6 ADDR %s): %s\n", __FUNCTION__, g_ral_ip_address, strerror(s)); - } - - return -1; - } - - s = bind(g_sockd_mihf, (const struct sockaddr *)addr6, sizeof(struct sockaddr_in)); - - if (s == -1) { - ERR(" RAL IPv6 Address Bind: %s\n", strerror(errno)); - return -1; - } - - if (connect(g_sockd_mihf, rp->ai_addr, rp->ai_addrlen) != -1) { - NOTICE(" RAL is now UDP-CONNECTED to MIH-F\n"); - freeaddrinfo(result); - return 0; - } else { - close(g_sockd_mihf); - } - } else { - ERR(" %s is an unknown address format %d\n",g_mihf_ip_address,rp->ai_family); - } - - close(g_sockd_mihf); - } - - if (rp == NULL) { /* No address succeeded */ - ERR(" Could not connect to MIH-F\n"); - return -1; - } - - return -1; -} -//----------------------------------------------------------------------------- -void mRALlte_send_link_register_indication(MIH_C_TRANSACTION_ID_T *transaction_idP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Register_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Register_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)6; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - - message.primitive.Link_Id.link_type = MIH_C_WIRELESS_UMTS; - message.primitive.Link_Id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - - MIH_C_3GPP_ADDR_set(&message.primitive.Link_Id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP, strlen(DEFAULT_ADDRESS_3GPP)); - //MIH_C_3GPP_ADDR_load_3gpp_str_address(&message.primitive.Link_Id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP); - - message_total_length = MIH_C_Link_Message_Encode_Link_Register_indication(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - MIH_C_LINK_ID2String(&message.primitive.Link_Id, g_msc_gen_buf); -#endif - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Register.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Register.indication\\n%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Register.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Register.indication\\n%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} -//----------------------------------------------------------------------------- -void mRALlte_send_link_detected_indication(MIH_C_TRANSACTION_ID_T *transaction_idP, MIH_C_LINK_DET_INFO_T *link_detected_infoP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Detected_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Detected_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - - memcpy(&message.primitive.LinkDetectedInfo, link_detected_infoP, sizeof(MIH_C_LINK_DET_INFO_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Detected_indication(bb, &message); - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Detected.indication\n"); -#ifdef MSCGEN_PYTOOL - g_msc_gen_buffer_index = 0; - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = MIH_C_SIG_STRENGTH2String(&link_detected_infoP->sig_strength, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index = sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nSINR %d\\nData rate %d", link_detected_infoP->sinr, link_detected_infoP->link_data_rate); - NOTICE("[MSC_MSG][%s][%s][--- Link_Detected.indication\\n%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Detected.indication\n"); -#ifdef MSCGEN_PYTOOL - g_msc_gen_buffer_index = 0; - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = MIH_C_SIG_STRENGTH2String(&link_detected_infoP->sig_strength, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index = sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nSINR %d\\nData rate %d", link_detected_infoP->sinr, link_detected_infoP->link_data_rate); - - NOTICE("[MSC_MSG][%s][%s][--- Link_Detected.indication\\n%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} -//----------------------------------------------------------------------------- -void mRALlte_send_link_up_indication(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_LINK_ADDR_T *old_access_routerP, - MIH_C_LINK_ADDR_T *new_access_routerP, - MIH_C_IP_RENEWAL_FLAG_T *ip_renewal_flagP, - MIH_C_IP_MOB_MGMT_T *mobility_management_supportP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Up_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Up_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)2; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, link_identifierP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - - message.primitive.OldAccessRouter = old_access_routerP; - message.primitive.NewAccessRouter = new_access_routerP; - message.primitive.IPRenewalFlag = ip_renewal_flagP; - message.primitive.MobilityManagementSupport = mobility_management_supportP; - - message_total_length = MIH_C_Link_Message_Encode_Link_Up_indication(bb, &message); - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Up.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Up.indication ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Up.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Up.indication --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} -//----------------------------------------------------------------------------- -void mRALlte_send_link_parameters_report_indication(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_LINK_PARAM_RPT_LIST_T *link_parameters_report_listP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Parameters_Report_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; -#ifdef MSCGEN_PYTOOL - unsigned int index; -#endif - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Parameters_Report_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)5; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, link_identifierP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - memcpy(&message.primitive.LinkParametersReportList_list, link_parameters_report_listP, sizeof(MIH_C_LINK_PARAM_RPT_LIST_T)); - - message_total_length = MIH_C_Link_Message_Encode_Link_Parameters_Report_indication(bb, &message); - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Parameters_Report.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Parameters_Report.indication ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Parameters_Report.indication\n"); -#ifdef MSCGEN_PYTOOL - g_msc_gen_buffer_index = 0; - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index += MIH_C_LINK_ID2String(&link_identifierP->link_id, &g_msc_gen_buf[g_msc_gen_buffer_index]); - - for (index = 0; index < link_parameters_report_listP->length; index++) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n"); - g_msc_gen_buffer_index += MIH_C_LINK_PARAM_RPT2String(&link_parameters_report_listP->val[index], &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - - NOTICE("[MSC_MSG][%s][%s][--- Link_Parameters_Report.indication\\n%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} -//----------------------------------------------------------------------------- -void mRALlte_send_link_going_down_indication(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_UNSIGNED_INT2_T *time_intervalP, - MIH_C_LINK_GD_REASON_T *link_going_down_reasonP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Going_Down_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Going_Down_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)6; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, link_identifierP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - message.primitive.TimeInterval = *time_intervalP; - memcpy(&message.primitive.LinkGoingDownReason, link_going_down_reasonP, sizeof(MIH_C_LINK_GD_REASON_T)); - - - message_total_length = MIH_C_Link_Message_Encode_Link_Going_Down_indication(bb, &message); - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Going_Down.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Going_Down.indication ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Going_Down.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Going_Down.indication --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} -//----------------------------------------------------------------------------- -void mRALlte_send_link_down_indication(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_LINK_TUPLE_ID_T *link_identifierP, - MIH_C_LINK_ADDR_T *old_access_routerP, - MIH_C_LINK_DN_REASON_T *reason_codeP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Down_indication_t message; - Bit_Buffer_t *bb; - int message_total_length; - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Going_Down_indication_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)2; - message.header.operation_code = (MIH_C_OPCODE_T)3; - message.header.action_identifier = (MIH_C_AID_T)3; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - - memcpy(&message.primitive.LinkIdentifier, link_identifierP, sizeof(MIH_C_LINK_TUPLE_ID_T)); - message.primitive.OldAccessRouter = old_access_routerP; - memcpy(&message.primitive.ReasonCode, reason_codeP, sizeof(MIH_C_LINK_DN_REASON_T)); - - - message_total_length = MIH_C_Link_Message_Encode_Link_Down_indication(bb, &message); - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Down.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Down.indication ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Down.indication\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Down.indication --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} -//----------------------------------------------------------------------------- -void mRALlte_send_link_action_confirm(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_SCAN_RSP_LIST_T *scan_response_setP, - MIH_C_LINK_AC_RESULT_T *link_action_resultP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Action_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; -#ifdef MSCGEN_PYTOOL - unsigned int index; -#endif - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Action_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)3; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - - message.primitive.Status = *statusP; - message.primitive.ScanResponseSet_list = scan_response_setP; - message.primitive.LinkActionResult = link_action_resultP; - - - message_total_length = MIH_C_Link_Message_Encode_Link_Action_confirm(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - - if (scan_response_setP) { - for (index = 0; index < scan_response_setP->length; index++) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nScan resp:"); - g_msc_gen_buffer_index += MIH_C_LINK_SCAN_RSP2String(&scan_response_setP->val[index], &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - } - - if (link_action_resultP) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nAction result:"); - g_msc_gen_buffer_index += MIH_C_LINK_AC_RESULT2String2(link_action_resultP, &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - -#endif - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Action.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Action.confirm\\nstatus=%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Action.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Action.confirm\\nstatus=%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} - -//----------------------------------------------------------------------------- -void mRALte_send_capability_discover_confirm(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *supported_link_event_listP, - MIH_C_LINK_CMD_LIST_T *supported_link_command_listP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Capability_Discover_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Capability_Discover_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.SupportedLinkEventList = supported_link_event_listP; - message.primitive.SupportedLinkCommandList = supported_link_command_listP; - - message_total_length = MIH_C_Link_Message_Encode_Capability_Discover_confirm(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n\\nsupported link events="); - g_msc_gen_buffer_index += MIH_C_LINK_EVENT_LIST2String2(message.primitive.SupportedLinkEventList, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nsupported commands="); - g_msc_gen_buffer_index += MIH_C_LINK_CMD_LIST2String2(message.primitive.SupportedLinkCommandList, &g_msc_gen_buf[g_msc_gen_buffer_index]); -#endif - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Capability_Discover.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Capability_Discover.confirm\\nstatus=%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Capability_Discover.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Capability_Discover.confirm\\nstatus=%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} -//----------------------------------------------------------------------------- -void mRALte_send_event_subscribe_confirm(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *response_link_event_listP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Event_Subscribe_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Event_Subscribe_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)4; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.ResponseLinkEventList = response_link_event_listP; - - message_total_length = MIH_C_Link_Message_Encode_Event_Subscribe_confirm(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nlink event list="); - g_msc_gen_buffer_index += MIH_C_LINK_EVENT_LIST2String2(message.primitive.ResponseLinkEventList, &g_msc_gen_buf[g_msc_gen_buffer_index]); -#endif - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Event_Subscribe.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Subscribe.confirm\\nstatus=%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Event_Subscribe.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Subscribe.confirm\\nstatus=%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} -//----------------------------------------------------------------------------- -void mRALte_send_event_unsubscribe_confirm(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_EVENT_LIST_T *response_link_event_listP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Event_Unsubscribe_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Event_Unsubscribe_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)1; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)5; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.ResponseLinkEventList = response_link_event_listP; - - message_total_length = MIH_C_Link_Message_Encode_Event_Unsubscribe_confirm(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nlink event list="); - g_msc_gen_buffer_index += MIH_C_LINK_EVENT_LIST2String2(message.primitive.ResponseLinkEventList, &g_msc_gen_buf[g_msc_gen_buffer_index]); -#endif - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Event_Unsubscribe.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Unsubscribe.confirm\\nstatus=%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Event_Unsubscribe.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Unsubscribe.confirm\\nstatus=%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} -//----------------------------------------------------------------------------- -void mRALte_send_configure_thresholds_confirm(MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_CFG_STATUS_LIST_T *link_configure_status_listP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Configure_Thresholds_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; -#ifdef MSCGEN_PYTOOL - int i; -#endif - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Configure_Thresholds_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)2; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.LinkConfigureStatusList_list = link_configure_status_listP; - - message_total_length = MIH_C_Link_Message_Encode_Configure_Thresholds_confirm(bb, &message); - -#ifdef MSCGEN_PYTOOL - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n"); - - for (i = 0; i < link_configure_status_listP->length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_CFG_STATUS2String(&link_configure_status_listP->val[i], &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - -#endif - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Configure_Threshold.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Configure_Thresholds.confirm\\nstatus=%s ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Configure_Threshold.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Configure_Thresholds.confirm\\nstatus=%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} -//----------------------------------------------------------------------------- -void mRALte_send_get_parameters_confirm (MIH_C_TRANSACTION_ID_T *transaction_idP, - MIH_C_STATUS_T *statusP, - MIH_C_LINK_PARAM_LIST_T *link_parameters_status_listP, - MIH_C_LINK_STATES_RSP_LIST_T *link_states_response_listP, - MIH_C_LINK_DESC_RSP_LIST_T *link_descriptors_response_listP) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Link_Get_Parameters_confirm_t message; - Bit_Buffer_t *bb; - int message_total_length; -#ifdef MSCGEN_PYTOOL - char msg_src[32]; - char msg_dst[32]; - int i; -#endif - - bb = new_BitBuffer_0(); - BitBuffer_wrap(bb, g_msg_codec_send_buffer, (unsigned int)MSG_CODEC_SEND_BUFFER_SIZE); - - memset(&message, 0, sizeof (MIH_C_Message_Link_Get_Parameters_confirm_t)); - - message.header.version = (MIH_C_VERSION_T)MIH_C_PROTOCOL_VERSION; - //message.header.ack_req = 0; - //message.header.ack_rsp = 0; - //message.header.uir = 0; - //message.header.more_fragment = 0 - //message.header.fragment_number = 0; - message.header.service_identifier = (MIH_C_SID_T)3; - message.header.operation_code = (MIH_C_OPCODE_T)0; - message.header.action_identifier = (MIH_C_AID_T)1; - message.header.transaction_id = *transaction_idP; - - - MIH_C_MIHF_ID_set(&message.source, (u_int8_t*)g_link_id, strlen(g_link_id)); - MIH_C_MIHF_ID_set(&message.destination, (u_int8_t*)g_mihf_id, strlen(g_mihf_id)); - - message.primitive.Status = *statusP; - message.primitive.LinkParametersStatusList_list = link_parameters_status_listP; - message.primitive.LinkStatesResponse_list = link_states_response_listP; - message.primitive.LinkDescriptorsResponse_list = link_descriptors_response_listP; - - message_total_length = MIH_C_Link_Message_Encode_Get_Parameters_confirm(bb, &message); - - if (mRALlte_send_to_mih(bb->m_buffer,message_total_length)<0) { - ERR(": Send Link_Get_Parameters.confirm\n"); -#ifdef MSCGEN_PYTOOL - NOTICE("[MSC_MSG][%s][%s][--- Link_Get_Parameters.confirm ---x][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_mihf_id); -#endif - } else { - DEBUG(": Sent Link_Get_Parameters.confirm\n"); -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&message.source, msg_src); - MIH_C_MIHF_ID2String(&message.destination, msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_STATUS2String(&message.primitive.Status, &g_msc_gen_buf[g_msc_gen_buffer_index]); - - if (link_parameters_status_listP) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n LinkParametersStatusList="); - - for (i = 0; i < link_parameters_status_listP->length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_PARAM2String(&link_parameters_status_listP->val[i], &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], ", "); - } - } - - if (link_states_response_listP) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n LinkStatesResponseList="); - - for (i = 0; i < link_states_response_listP->length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_STATES_RSP2String(&link_states_response_listP->val[i], &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], ", "); - } - } - - if (link_descriptors_response_listP) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n LinkDescriptorsResponseList="); - - for (i = 0; i < link_descriptors_response_listP->length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_DESC_RSP2String(&link_descriptors_response_listP->val[i], &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], ", "); - } - } - - NOTICE("[MSC_MSG][%s][%s][--- Link_Get_Parameters.confirm\\n%s --->][%s]\n", - getTimeStamp4Log(), - g_link_id, - g_msc_gen_buf, - g_mihf_id); -#endif - } - - free_BitBuffer(bb); -} -//----------------------------------------------------------------------------- -int mRALlte_mih_link_msg_decode(Bit_Buffer_t* bbP, MIH_C_Message_Wrapper_t *message_wrapperP) -{ - //----------------------------------------------------------------------------- - int status = MIH_MESSAGE_DECODE_FAILURE; - MIH_C_HEADER_T header; - MIH_C_STATUS_T mih_status; -#ifdef MSCGEN_PYTOOL - char msg_src[32]; - char msg_dst[32]; - int i; -#endif - - if ((bbP != NULL) && (message_wrapperP != NULL)) { - status = MIH_C_Link_Header_Decode(bbP, &header); - - if (status == MIH_HEADER_DECODE_TOO_SHORT) { - return MIH_MESSAGE_DECODE_TOO_SHORT; - } else if (status == MIH_HEADER_DECODE_FAILURE) { - return MIH_MESSAGE_DECODE_FAILURE; - } else if (status == MIH_HEADER_DECODE_BAD_PARAMETER) { - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - message_wrapperP->message_id = MIH_C_MESSAGE_ID(header.service_identifier, header.operation_code, header.action_identifier); - - switch (message_wrapperP->message_id) { - case MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_REQUEST_ID: - DEBUG(" %s Received MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_capability_discover_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Capability_Discover_request(bbP, &message_wrapperP->_union_message.link_capability_discover_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_capability_discover_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_capability_discover_request.destination), msg_dst); - NOTICE("[MSC_MSG][%s][%s][--- Link_Capability_Discover.request --->][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - MIH_C_Link_Message_Link_Capability_Discover_request2String(&message_wrapperP->_union_message.link_capability_discover_request, g_msg_print_buffer); - DEBUG("%s", g_msg_print_buffer); - - mih_status = MIH_C_STATUS_SUCCESS; - DEBUG("**\n"); - DEBUG(" %s Sending MIH_C_MESSAGE_LINK_CAPABILITY_DISCOVER_CONFIRM\n\n", __FUNCTION__); - - mRALte_send_capability_discover_confirm(&message_wrapperP->_union_message.link_capability_discover_request.header.transaction_id, - &mih_status, - &ralpriv->mih_supported_link_event_list, - &ralpriv->mih_supported_link_command_list); - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_capability_discover_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_capability_discover_request.destination), msg_dst); - NOTICE("[MSC_MSG][%s][%s][--- Link_Capability_Discover.request\\nERR DECODE ---x][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - case MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_REQUEST_ID: - DEBUG(" %s Received MIH_C_MESSAGE_LINK_EVENT_SUBSCRIBE_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_event_subscribe_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Event_Subscribe_request(bbP, &message_wrapperP->_union_message.link_event_subscribe_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_subscribe_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_subscribe_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - MIH_C_LINK_EVENT_LIST2String2(&message_wrapperP->_union_message.link_event_subscribe_request.primitive.RequestedLinkEventList, g_msc_gen_buf); - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Subscribe.request\\n%s --->][%s]\n", - getTimeStamp4Log(), - msg_src, - g_msc_gen_buf, - msg_dst); -#endif - DEBUG("**\n"); - - mRALlte_subscribe_request(&message_wrapperP->_union_message.link_event_subscribe_request); - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_subscribe_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_subscribe_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - MIH_C_LINK_EVENT_LIST2String2(&message_wrapperP->_union_message.link_event_subscribe_request.primitive.RequestedLinkEventList, g_msc_gen_buf); - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Subscribe.request\\nERR DECODE ---x][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - case MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_REQUEST_ID: - DEBUG(" %s Received MIH_C_MESSAGE_LINK_EVENT_UNSUBSCRIBE_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_event_unsubscribe_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Event_Unsubscribe_request(bbP, &message_wrapperP->_union_message.link_event_unsubscribe_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_unsubscribe_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_unsubscribe_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - MIH_C_LINK_EVENT_LIST2String2(&message_wrapperP->_union_message.link_event_unsubscribe_request.primitive.RequestedLinkEventList, g_msc_gen_buf); - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Unsubscribe.request\\n%s --->][%s]\n", - getTimeStamp4Log(), - msg_src, - g_msc_gen_buf, - msg_dst); -#endif - DEBUG("**\n"); - mRALlte_unsubscribe_request(&message_wrapperP->_union_message.link_event_unsubscribe_request); - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_unsubscribe_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_event_unsubscribe_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - MIH_C_LINK_EVENT_LIST2String2(&message_wrapperP->_union_message.link_event_unsubscribe_request.primitive.RequestedLinkEventList, g_msc_gen_buf); - NOTICE("[MSC_MSG][%s][%s][--- Link_Event_Unsubscribe.request\\nERR DECODE ---x][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - case MIH_C_MESSAGE_LINK_GET_PARAMETERS_REQUEST_ID: - DEBUG(" %s Received MIH_C_MESSAGE_LINK_GET_PARAMETERS_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_get_parameters_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Get_Parameters_request(bbP, &message_wrapperP->_union_message.link_get_parameters_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_get_parameters_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_get_parameters_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - - for (i = 0; i < message_wrapperP->_union_message.link_get_parameters_request.primitive.LinkParametersRequest_list.length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_PARAM_TYPE2String(&message_wrapperP->_union_message.link_get_parameters_request.primitive.LinkParametersRequest_list.val[i], - &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n Link states request="); - g_msc_gen_buffer_index += MIH_C_LINK_STATES_REQ2String2(&message_wrapperP->_union_message.link_get_parameters_request.primitive.LinkStatesRequest, &g_msc_gen_buf[g_msc_gen_buffer_index]); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\n Link desc request="); - g_msc_gen_buffer_index += MIH_C_LINK_DESC_REQ2String2(&message_wrapperP->_union_message.link_get_parameters_request.primitive.LinkDescriptorsRequest, &g_msc_gen_buf[g_msc_gen_buffer_index]); - - NOTICE("[MSC_MSG][%s][%s][--- Link_Get_Parameters.request\\n%s --->][%s]\n", - getTimeStamp4Log(), - msg_src, - g_msc_gen_buf, - msg_dst); -#endif - DEBUG("**\n"); - mRALlte_get_parameters_request(&message_wrapperP->_union_message.link_get_parameters_request); - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_get_parameters_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_get_parameters_request.destination), msg_dst); - NOTICE("[MSC_MSG][%s][%s][--- Link_Get_Parameters.request\\nERR DECODE ---x][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - case MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_REQUEST_ID: - DEBUG(" %s Received MIH_C_MESSAGE_LINK_CONFIGURE_THRESHOLDS_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_configure_thresholds_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Configure_Thresholds_request(bbP, &message_wrapperP->_union_message.link_configure_thresholds_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_configure_thresholds_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_configure_thresholds_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - - for (i = 0; i < message_wrapperP->_union_message.link_configure_thresholds_request.primitive.LinkConfigureParameterList_list.length; i++) { - g_msc_gen_buffer_index += MIH_C_LINK_CFG_PARAM2String(&message_wrapperP->_union_message.link_configure_thresholds_request.primitive.LinkConfigureParameterList_list.val[i], - &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - - NOTICE("[MSC_MSG][%s][%s][--- Link_Configure_Thresholds.request\\n%s --->][%s]\n", - getTimeStamp4Log(), - msg_src, - g_msc_gen_buf, - msg_dst); -#endif - DEBUG("**\n"); - mRALlte_configure_thresholds_request(&message_wrapperP->_union_message.link_configure_thresholds_request); - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_configure_thresholds_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_configure_thresholds_request.destination), msg_dst); - NOTICE("[MSC_MSG][%s][%s][--- Link_Configure_Thresholds.request\\nERR DECODE ---x][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - case MIH_C_MESSAGE_LINK_ACTION_REQUEST_ID: - DEBUG(" %s Received MIH_C_MESSAGE_LINK_ACTION_REQUEST\n", __FUNCTION__); - memcpy(&message_wrapperP->_union_message.link_action_request.header, (const void *)&header, sizeof(MIH_C_HEADER_T)); - status = MIH_C_Link_Message_Decode_Link_Action_request(bbP, &message_wrapperP->_union_message.link_action_request); - - if (status == MIH_MESSAGE_DECODE_OK) { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_action_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_action_request.destination), msg_dst); - memset(g_msc_gen_buf, 0, MSC_GEN_BUF_SIZE); - g_msc_gen_buffer_index = 0; - g_msc_gen_buffer_index += MIH_C_LINK_ACTION2String(&message_wrapperP->_union_message.link_action_request.primitive.LinkAction, g_msc_gen_buf); - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nExecution Delay=%d", message_wrapperP->_union_message.link_action_request.primitive.ExecutionDelay); - - if (message_wrapperP->_union_message.link_action_request.primitive.PoALinkAddress != NULL) { - g_msc_gen_buffer_index += sprintf(&g_msc_gen_buf[g_msc_gen_buffer_index], "\\nPoALinkAddress="); - g_msc_gen_buffer_index += MIH_C_LINK_ADDR2String(message_wrapperP->_union_message.link_action_request.primitive.PoALinkAddress, &g_msc_gen_buf[g_msc_gen_buffer_index]); - } - - NOTICE("[MSC_MSG][%s][%s][--- Link_Action.request\\n%s --->][%s]\n", - getTimeStamp4Log(), - msg_src, - g_msc_gen_buf, - msg_dst); -#endif - DEBUG("**\n"); - mRALlte_action_request(&message_wrapperP->_union_message.link_action_request); - } else { -#ifdef MSCGEN_PYTOOL - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_action_request.source), msg_src); - MIH_C_MIHF_ID2String(&(message_wrapperP->_union_message.link_action_request.destination), msg_dst); - NOTICE("[MSC_MSG][%s][%s][--- Link_Action.request\\nERR DECODE --->][%s]\n", - getTimeStamp4Log(), - msg_src, - msg_dst); -#endif - } - - break; - - default: - WARNING("UNKNOWN MESSAGE ID SID %d, OP_CODE %d, AID %d\n", header.service_identifier, header.operation_code, header.action_identifier); - status = MIH_MESSAGE_DECODE_FAILURE; - - return status; - } - } else { - return MIH_MESSAGE_DECODE_BAD_PARAMETER; - } - - return status; -} -//----------------------------------------------------------------------------- -int mRALlte_mih_link_process_message(void) -{ - //----------------------------------------------------------------------------- - MIH_C_Message_Wrapper_t message_wrapper; - int nb_bytes_received ; - int nb_bytes_decoded ; - int total_bytes_to_decode ; - int status ; - Bit_Buffer_t *bb; - struct sockaddr_in udp_socket; - socklen_t sockaddr_len; - - - total_bytes_to_decode = 0; - nb_bytes_received = 0; - - bb = new_BitBuffer_0(); - - nb_bytes_received = recvfrom(g_sockd_mihf, - (void *)g_msg_codec_recv_buffer, - MSG_CODEC_RECV_BUFFER_SIZE, - 0, - (struct sockaddr *) &udp_socket, - &sockaddr_len); - - if (nb_bytes_received > 0) { - DEBUG(" \n"); - DEBUG(" %s Received %d bytes from MIHF\n", __FUNCTION__, nb_bytes_received); - mRALlte_print_buffer((char*)g_msg_codec_recv_buffer, nb_bytes_received); - total_bytes_to_decode += nb_bytes_received; - BitBuffer_wrap(bb, g_msg_codec_recv_buffer, total_bytes_to_decode); - status = mRALlte_mih_link_msg_decode(bb, &message_wrapper); - nb_bytes_decoded = BitBuffer_getPosition(bb); - - if (status == MIH_MESSAGE_DECODE_OK) { - if (nb_bytes_decoded > 0) { - total_bytes_to_decode = total_bytes_to_decode - nb_bytes_decoded; - - // if remaining bytes to decode - if (total_bytes_to_decode > 0) { - //shift left bytes in buffer - memcpy(g_msg_codec_recv_buffer, &g_msg_codec_recv_buffer[nb_bytes_decoded], nb_bytes_decoded); - - //shift left again bytes in buffer - if (total_bytes_to_decode > nb_bytes_decoded) { - memcpy(&g_msg_codec_recv_buffer[nb_bytes_decoded], &g_msg_codec_recv_buffer[nb_bytes_decoded], total_bytes_to_decode - nb_bytes_decoded); - } - - // not necessary - memset(&g_msg_codec_recv_buffer[total_bytes_to_decode], 0 , MSG_CODEC_RECV_BUFFER_SIZE - total_bytes_to_decode); - - } - } - - // data could not be decoded - } else if (status == MIH_MESSAGE_DECODE_FAILURE) { - memset(g_msg_codec_recv_buffer, 0, MSG_CODEC_RECV_BUFFER_SIZE); - total_bytes_to_decode = 0; - } else if ((status == MIH_MESSAGE_DECODE_TOO_SHORT)) { - } - - DEBUG(" \n"); - } - - free_BitBuffer(bb); - return 0; -} diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_parameters.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_parameters.c deleted file mode 100755 index 7fffeacd8b..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_parameters.c +++ /dev/null @@ -1,136 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#define MRAL_MODULE -#define MRALLTE_PARAMETERS_C -#include <assert.h> -#include "mRALlte_parameters.h" - -//----------------------------------------------------------------------------- -void mRALlte_get_parameters_request(MIH_C_Message_Link_Get_Parameters_request_t* messageP) -{ - //----------------------------------------------------------------------------- - MIH_C_STATUS_T status; - MIH_C_LINK_PARAM_LIST_T link_parameters_status_list; - MIH_C_LINK_STATES_RSP_LIST_T link_states_response_list; - MIH_C_LINK_DESC_RSP_LIST_T link_descriptors_response_list; - unsigned int link_index; - - // SAVE REQUEST - // MAY BE MERGE REQUESTS ? - //memcpy(&g_link_cfg_param_thresholds_list, &messageP->primitive.LinkConfigureParameterList_list, sizeof(MIH_C_LINK_CFG_PARAM_LIST_T)); - - status = MIH_C_STATUS_SUCCESS; - - for (link_index = 0; - link_index < messageP->primitive.LinkParametersRequest_list.length; - link_index++) { - - //------------------------------------------------ - // MIH_C_LINK_PARAM_LIST_T - //------------------------------------------------ - memcpy(&link_parameters_status_list.val[link_index].link_param_type, - &messageP->primitive.LinkParametersRequest_list.val[link_index], - sizeof(MIH_C_LINK_PARAM_TYPE_T)); - - switch (messageP->primitive.LinkParametersRequest_list.val[link_index].choice) { - case MIH_C_LINK_PARAM_TYPE_CHOICE_GEN: - link_parameters_status_list.val[link_index].choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - link_parameters_status_list.val[link_index]._union.link_param_val = MIH_C_LINK_PARAM_GEN_SIGNAL_STRENGTH; - break; - - case MIH_C_LINK_PARAM_TYPE_CHOICE_QOS: - link_parameters_status_list.val[link_index].choice = MIH_C_LINK_PARAM_CHOICE_QOS_PARAM_VAL; - link_parameters_status_list.val[link_index]._union.qos_param_val.choice = MIH_C_QOS_PARAM_VAL_CHOICE_AVG_PK_TX_DELAY; - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.length = 2; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[0].cos_id = 2; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[0].value = 20; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[1].cos_id = 3; //?? - link_parameters_status_list.val[link_index]._union.qos_param_val._union.avg_pk_tx_delay_list.val[2].value = 50; //?? - break; - - case MIH_C_LINK_PARAM_TYPE_CHOICE_LTE: - case MIH_C_LINK_PARAM_TYPE_CHOICE_GG: - case MIH_C_LINK_PARAM_TYPE_CHOICE_EDGE: - case MIH_C_LINK_PARAM_TYPE_CHOICE_ETH: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_11: - case MIH_C_LINK_PARAM_TYPE_CHOICE_C2K: - case MIH_C_LINK_PARAM_TYPE_CHOICE_FDD: - case MIH_C_LINK_PARAM_TYPE_CHOICE_HRPD: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_16: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_20: - case MIH_C_LINK_PARAM_TYPE_CHOICE_802_22: - default: - ERR("%s TO DO CONTINUE PROCESSING LinkParametersRequest_list of \n", __FUNCTION__); - } - - //------------------------------------------------ - // MIH_C_LINK_STATES_RSP_LIST_T - //------------------------------------------------ - if (messageP->primitive.LinkStatesRequest & MIH_C_BIT_LINK_STATES_REQ_OP_MODE) { - link_states_response_list.val[link_index].choice = 0; - link_states_response_list.val[link_index]._union.op_mode = MIH_C_OPMODE_NORMAL_MODE; - } else if (messageP->primitive.LinkStatesRequest & MIH_C_BIT_LINK_STATES_REQ_CHANNEL_ID) { - link_states_response_list.val[link_index].choice = 1; - link_states_response_list.val[link_index]._union.channel_id = PREDEFINED_CHANNEL_ID; - } else { - ERR("%s Invalid LinkStatesRequest in MIH_C_Link_Get_Parameters_request\n", __FUNCTION__); - // DEFAULT VALUES - link_states_response_list.val[link_index].choice = 0; - link_states_response_list.val[link_index]._union.op_mode = MIH_C_OPMODE_NORMAL_MODE; - } - - //------------------------------------------------ - // MIH_C_LINK_DESC_RSP_LIST_T - //------------------------------------------------ - if (messageP->primitive.LinkDescriptorsRequest & MIH_C_BIT_NUMBER_OF_CLASSES_OF_SERVICE_SUPPORTED) { - link_descriptors_response_list.val[link_index].choice = 0; - link_descriptors_response_list.val[link_index]._union.num_cos = PREDEFINED_CLASSES_SERVICE_SUPPORTED; - } else if (messageP->primitive.LinkDescriptorsRequest & MIH_C_BIT_NUMBER_OF_QUEUES_SUPPORTED) { - link_descriptors_response_list.val[link_index].choice = 1; - link_descriptors_response_list.val[link_index]._union.num_queue = PREDEFINED_QUEUES_SUPPORTED; - } else { - ERR("%s Invalid LinkDescriptorsRequest in MIH_C_Link_Get_Parameters_request\n", __FUNCTION__); - // DEFAULT VALUES - link_descriptors_response_list.val[link_index].choice = 0; - link_descriptors_response_list.val[link_index]._union.num_cos = PREDEFINED_CLASSES_SERVICE_SUPPORTED; - } - } - - link_parameters_status_list.length = messageP->primitive.LinkParametersRequest_list.length; - link_states_response_list.length = messageP->primitive.LinkParametersRequest_list.length; - link_descriptors_response_list.length = messageP->primitive.LinkParametersRequest_list.length; - - - mRALte_send_get_parameters_confirm(&messageP->header.transaction_id, - &status, - &link_parameters_status_list, - &link_states_response_list, - &link_descriptors_response_list); -} - diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_process.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_process.c deleted file mode 100755 index fde9fe9d54..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_process.c +++ /dev/null @@ -1,297 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#define MRAL_MODULE -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <sys/socket.h> - -#include "mRALlte_variables.h" -#include "mRALlte_proto.h" -#include "MIH_C.h" -#include "mRALlte_mih_msg.h" -#include "mRALlte_thresholds.h" -// for real-time -//#include "nas_ue_ioctl.h" -//#include "nasmt_constant.h" -// for dummy -#include "nas_ue_netlink.h" - -//global variables -extern int meas_counter; -extern int s_nas; - -//--------------------------------------------------------------------------- -// Temp - Enter hard-coded measures in IAL -void IAL_NAS_measures_init(void) -//--------------------------------------------------------------------------- -{ -#ifdef RAL_DUMMY - ralpriv->num_measures = 3; -#endif -#ifdef RAL_REALTIME - ralpriv->num_measures = 1; -#endif - ralpriv->meas_cell_id[0] = 0; -#ifdef MIH_USER_CONTROL - ralpriv->last_meas_level[0] = 0; -#else - ralpriv->last_meas_level[0] = 30; -#endif - ralpriv->integrated_meas_level[0] = ralpriv->last_meas_level[0]; - ralpriv->provider_id[0] = 25; - ralpriv->meas_cell_id[1] = 1; - ralpriv->last_meas_level[1] = 50; - ralpriv->integrated_meas_level[1] = ralpriv->last_meas_level[1]; - ralpriv->provider_id[1] = 1; - ralpriv->meas_cell_id[2] = 20; - ralpriv->last_meas_level[2] = 20; - ralpriv->integrated_meas_level[2] = ralpriv->last_meas_level[2]; - ralpriv->provider_id[2] = 25; -} - -//--------------------------------------------------------------------------- -// Temp - Enter hard-coded measures in IAL -void IAL_NAS_measures_update(int i) -//--------------------------------------------------------------------------- -{ - int j; - - //ralpriv->meas_cell_id[0] = ralpriv->cell_id; - j = i%2; - - if (j==0) { - ralpriv->integrated_meas_level[2] = (ralpriv->integrated_meas_level[2] + (ralpriv->last_meas_level[2]/5)); - } else { - ralpriv->integrated_meas_level[2] = (ralpriv->integrated_meas_level[2] - (ralpriv->last_meas_level[2]/5)); - } - - ralpriv->curr_signal_level = ralpriv->integrated_meas_level[0]; - - // DEBUG ("Measure update - cell 1 %d, %d \n", ralpriv->last_meas_level[1], ralpriv->integrated_meas_level[1]); -} - -//--------------------------------------------------------------------------- -void IAL_integrate_measure(int measure, int i) -{ - //--------------------------------------------------------------------------- - int new_integrated = 0; - - new_integrated = (((10-LAMBDA)*ralpriv->last_meas_level[i])+(LAMBDA*measure))/10; - //apply correction to get a value between 0-100 - now is linear - new_integrated = (new_integrated*100)/MEAS_MAX_RSSI; - // print result -#ifdef DEBUG_MRALU_MEASURES - DEBUG ("Integrate measure : old %d, new %d, integrated %d\n", ralpriv->last_meas_level[i], measure,new_integrated ); -#endif - // store the result - ralpriv->last_meas_level[i] = measure; - ralpriv->prev_integrated_meas_level[i] = ralpriv->integrated_meas_level[i]; - ralpriv->integrated_meas_level[i] = new_integrated; -} - - -//--------------------------------------------------------------------------- -// poll for measures in NAS -void rallte_NAS_measures_polling(void) -{ - //--------------------------------------------------------------------------- - MIH_C_LINK_GD_REASON_T going_down_reason_code; - MIH_C_LINK_DN_REASON_T down_reason_code; - MIH_C_TRANSACTION_ID_T transaction_id; - MIH_C_LINK_TUPLE_ID_T link_identifier; - MIH_C_LINK_DET_INFO_T link_detected_info; - MIH_C_UNSIGNED_INT2_T time_interval; - //MIH_C_LINK_PARAM_RPT_LIST_T link_parameters_report_list; - - IAL_process_DNAS_message(IO_OBJ_MEAS, IO_CMD_LIST, 0); - - // hard-coded trigger for test -#ifdef MRALU_SIMU_LINKDOWN - meas_counter ++; - - if (meas_counter == 4) { - ralpriv->curr_signal_level = ralpriv->curr_signal_level/10; - IAL_integrate_measure(ralpriv->curr_signal_level, 0); - DEBUG ("\n signal level %d , integrated new value : %d\n",ralpriv->curr_signal_level, ralpriv->integrated_meas_level[0]); - } - - if (meas_counter == 5) { - ralpriv->curr_signal_level = 40; - IAL_integrate_measure(ralpriv->curr_signal_level, 0); - DEBUG ("\n signal level %d , integrated new value : %d\n",ralpriv->curr_signal_level, ralpriv->integrated_meas_level[0]); - } - - if (meas_counter == 6) { - ralpriv->curr_signal_level = 0; - IAL_integrate_measure(ralpriv->curr_signal_level, 0); - DEBUG ("\n signal level %d , integrated new value : %d\n",ralpriv->curr_signal_level, ralpriv->integrated_meas_level[0]); - } - -#endif - DEBUG ("signal level %d , integrated new value : %d , integrated old value : (%d)\n", - ralpriv->curr_signal_level, - ralpriv->integrated_meas_level[0], - ralpriv->prev_integrated_meas_level[0]); - - // condition still TBD - message dropped or level = 0 - if ((!ralpriv->curr_signal_level) && - (ralpriv->link_to_be_detected == MIH_C_BOOLEAN_FALSE) && - (ralpriv->state != DISCONNECTED) - ) { - transaction_id = MIH_C_get_new_transaction_id(); - down_reason_code = MIH_C_LINK_DOWN_REASON_NO_RESOURCE; - link_identifier.link_id.link_type = MIH_C_WIRELESS_UMTS; - link_identifier.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_load_3gpp_str_address(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP); - link_identifier.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - - mRALlte_send_link_down_indication(&transaction_id, - &link_identifier, - NULL, - &down_reason_code); - - ralpriv->link_to_be_detected = MIH_C_BOOLEAN_TRUE; - // warning may be repeated several times - } else if ((ralpriv->link_to_be_detected == MIH_C_BOOLEAN_FALSE) && - (ralpriv->curr_signal_level <= ralpriv->integrated_meas_level[0]) && - (ralpriv->integrated_meas_level[0] < ralpriv->prev_integrated_meas_level[0]) && - (ralpriv->integrated_meas_level[0] < PREDEFINED_LINK_GOING_DOWN_INDICATION_SIG_STRENGTH) && - (ralpriv->state != DISCONNECTED) - ) { - transaction_id = MIH_C_get_new_transaction_id(); - - link_identifier.link_id.link_type = MIH_C_WIRELESS_UMTS; - link_identifier.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_load_3gpp_str_address(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP); - link_identifier.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - - time_interval = (MIH_C_UNSIGNED_INT2_T)0; // unknown - - going_down_reason_code = MIH_C_LINK_GOING_DOWN_REASON_LINK_PARAMETER_DEGRADING; - - mRALlte_send_link_going_down_indication(&transaction_id, - &link_identifier, - &time_interval, - &going_down_reason_code); - - } else if ((ralpriv->link_to_be_detected == MIH_C_BOOLEAN_TRUE) && (ralpriv->curr_signal_level > PREDEFINED_LINK_DETECTED_INDICATION_SIG_STRENGTH)) { - transaction_id = MIH_C_get_new_transaction_id(); - // MIH_C_LINK_TUPLE_ID_T - link_detected_info.link_tuple_id.link_id.link_type = MIH_C_WIRELESS_UMTS; - link_detected_info.link_tuple_id.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_set(&link_detected_info.link_tuple_id.link_id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP, strlen(DEFAULT_ADDRESS_3GPP)); - link_detected_info.link_tuple_id.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - // MIH_C_NETWORK_ID_T - MIH_C_NETWORK_ID_set(&link_detected_info.network_id, (u_int8_t *)PREDEFINED_MIH_NETWORK_ID, strlen(PREDEFINED_MIH_NETWORK_ID)); - // MIH_C_NET_AUX_ID_T - MIH_C_NET_AUX_ID_set(&link_detected_info.net_aux_id, (u_int8_t *)PREDEFINED_MIH_NETAUX_ID, strlen(PREDEFINED_MIH_NETAUX_ID)); - // MIH_C_SIG_STRENGTH_T - link_detected_info.sig_strength.choice = MIH_C_SIG_STRENGTH_CHOICE_PERCENTAGE; - link_detected_info.sig_strength._union.percentage = ralpriv->curr_signal_level; - // sinr - link_detected_info.sinr = PREDEFINED_LINK_DETECTED_INDICATION_SINR; - // MIH_C_LINK_DATA_RATE_T - link_detected_info.link_data_rate = PREDEFINED_LINK_DETECTED_INDICATION_LINK_DATA_RATE; - // MIH_C_LINK_MIHCAP_FLAG - link_detected_info.link_mihcap_flag = MIH_C_BIT_EVENT_SERVICE_SUPPORTED | - MIH_C_BIT_COMMAND_SERVICE_SUPPORTED | - MIH_C_BIT_INFORMATION_SERVICE_SUPPORTED; - // MIH_C_NET_CAPS_T - link_detected_info.net_caps = MIH_C_BIT_NET_CAPS_QOS_CLASS0 | - MIH_C_BIT_NET_CAPS_QOS_CLASS1 | - MIH_C_BIT_NET_CAPS_INTERNET_ACCESS; - - - mRALlte_send_link_detected_indication(&transaction_id, &link_detected_info); - ralpriv->link_to_be_detected = MIH_C_BOOLEAN_FALSE; - } - - // LG: TO DO CHECK IF INDEX IS 0 - mRALlte_check_thresholds_signal_strength(ralpriv->integrated_meas_level[0], ralpriv->prev_integrated_meas_level[0]); -} - -//--------------------------------------------------------------------------- -// find correponding cell in NAS measures -int rallte_NAS_corresponding_cell(int req_index) -//--------------------------------------------------------------------------- -{ - int index, i=0; - - while ((i<=ralpriv->num_measures)&&(ralpriv->req_cell_id[req_index]!=ralpriv->meas_cell_id[i])) - i++; - - index = i; - return index; -} - -//--------------------------------------------------------------------------- -void rallte_verifyPendingConnection(void) -{ - //--------------------------------------------------------------------------- - int if_ready = 0; - - if ((ralpriv->pending_req_flag)%5==0) { - DEBUG("Pending Req Flag %d\n", ralpriv->pending_req_flag); - DEBUG(" >>>> rallte_verifyPendingConnection "); - //poll status from driver -#ifdef RAL_DUMMY - IAL_process_DNAS_message(IO_OBJ_CNX, IO_CMD_LIST, ralpriv->cell_id); - - if ((ralpriv->nas_state == NAS_CONNECTED)&&(ralpriv->num_rb>=1)) { - if_ready = 1; - ralpriv->state = CONNECTED; - } - -#endif -#ifdef RAL_REALTIME - IAL_process_NAS_message(IO_OBJ_CNX, IO_CMD_LIST, ralpriv->cell_id); - - if ((ralpriv->nas_state == GRAAL_CX_DCH)&&(ralpriv->num_rb>=1)) { - if_ready = 1; - ralpriv->state = CONNECTED; - } - -#endif - - if ((if_ready==1)||(ralpriv->pending_req_flag > 100)) { - // here or just after ioctl? or between? - //mRALu_send_link_switch_cnf(); - //mRALte_send_link_action_confirm(); - - mRALlte_send_link_action_confirm(&ralpriv->pending_req_transaction_id, &ralpriv->pending_req_status, NULL, &ralpriv->pending_req_ac_result); - - DEBUG("After response, Pending Req Flag = %d\n", ralpriv->pending_req_flag); - ralpriv->pending_req_flag = 0; - // Link_up Ind not needed anymore - //sleep(2); - //mRALte_send_link_up_indication(); - } - } -} diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_subscribe.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_subscribe.c deleted file mode 100755 index e9473adba6..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_subscribe.c +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#define MRAL_MODULE -#define MRALLTE_SUBSCRIBE_C -#include <assert.h> -#include "mRALlte_subscribe.h" -#include "mRALlte_variables.h" - -//----------------------------------------------------------------------------- -void mRALlte_subscribe_request(MIH_C_Message_Link_Event_Subscribe_request_t* messageP) -{ - //----------------------------------------------------------------------------- - MIH_C_STATUS_T status; - MIH_C_LINK_EVENT_LIST_T mih_subscribed_req_event_list; - - ralpriv->mih_subscribe_req_event_list |= (messageP->primitive.RequestedLinkEventList & ralpriv->mih_supported_link_event_list); - - mih_subscribed_req_event_list = ralpriv->mih_subscribe_req_event_list & messageP->primitive.RequestedLinkEventList; - - status = MIH_C_STATUS_SUCCESS; - - mRALte_send_event_subscribe_confirm(&messageP->header.transaction_id, - &status, - &mih_subscribed_req_event_list); - -} -//----------------------------------------------------------------------------- -void mRALlte_unsubscribe_request(MIH_C_Message_Link_Event_Unsubscribe_request_t* messageP) -{ - //----------------------------------------------------------------------------- - MIH_C_STATUS_T status; - MIH_C_LINK_EVENT_LIST_T mih_unsubscribed_req_event_list; - MIH_C_LINK_EVENT_LIST_T saved_req_event_list; - - saved_req_event_list = ralpriv->mih_subscribe_req_event_list; - - ralpriv->mih_subscribe_req_event_list &= ((messageP->primitive.RequestedLinkEventList & ralpriv->mih_supported_link_event_list) ^ - messageP->primitive.RequestedLinkEventList); - - mih_unsubscribed_req_event_list = ralpriv->mih_subscribe_req_event_list ^ saved_req_event_list; - - status = MIH_C_STATUS_SUCCESS; - - mRALte_send_event_unsubscribe_confirm(&messageP->header.transaction_id, - &status, - &mih_unsubscribed_req_event_list); -} - - diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_thresholds.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_thresholds.c deleted file mode 100755 index 8ea0ef24ac..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/mRALlte_thresholds.c +++ /dev/null @@ -1,219 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#define MRAL_MODULE -#define MRALLTE_THRESHOLDS_C -#include <assert.h> -#include "mRALlte_thresholds.h" -#include "mRALlte_variables.h" - -//----------------------------------------------------------------------------- -void mRALlte_configure_thresholds_request(MIH_C_Message_Link_Configure_Thresholds_request_t* messageP) -{ - //----------------------------------------------------------------------------- - MIH_C_STATUS_T status; - MIH_C_LINK_CFG_STATUS_LIST_T link_cfg_status_list; - unsigned int threshold_index; - unsigned int link_index; - unsigned int result_index; - - // SAVE REQUEST - // IT IS ASSUMED SINCE IT IS NOT CLEAR IN SPECs THAT THERE IS NO NEED TO MERGE CONFIGURE_THRESHOLDS_requests - //memset(&ralpriv->mih_link_cfg_param_thresholds_list, 0, sizeof(MIH_C_LINK_CFG_PARAM_LIST_T)); - memcpy(&ralpriv->mih_link_cfg_param_thresholds_list, &messageP->primitive.LinkConfigureParameterList_list, sizeof(MIH_C_LINK_CFG_PARAM_LIST_T)); - - status = MIH_C_STATUS_SUCCESS; - - result_index = 0; - - for (link_index = 0; - link_index < messageP->primitive.LinkConfigureParameterList_list.length; - link_index++) { - - ralpriv->active_mih_link_cfg_param_threshold[link_index] = MIH_C_BOOLEAN_TRUE; - - for (threshold_index = 0; - threshold_index < messageP->primitive.LinkConfigureParameterList_list.val[link_index].threshold_list.length; - threshold_index ++) { - - memcpy(&link_cfg_status_list.val[result_index].link_param_type, - &messageP->primitive.LinkConfigureParameterList_list.val[link_index].link_param_type, - sizeof(MIH_C_LINK_PARAM_TYPE_T)); - - memcpy(&link_cfg_status_list.val[result_index].threshold, - &messageP->primitive.LinkConfigureParameterList_list.val[link_index].threshold_list.val[threshold_index], - sizeof(MIH_C_THRESHOLD_T)); - - // NOW, ALWAYS SAY OK FOR PARAMETERS, BUT MAY BE WE WILL PUT MIH_C_BOOLEAN_FALSE in active_mih_link_cfg_param_threshold[link_index] - link_cfg_status_list.val[result_index].config_status = MIH_C_CONFIG_STATUS_SUCCESS; - - result_index += 1; - } - } - - // Say following thresholds entries are not configured - for (link_index = messageP->primitive.LinkConfigureParameterList_list.length; - link_index < MIH_C_LINK_CFG_PARAM_LIST_LENGTH; - link_index++) { - ralpriv->active_mih_link_cfg_param_threshold[link_index] = MIH_C_BOOLEAN_FALSE; - } - - link_cfg_status_list.length = result_index; - - mRALte_send_configure_thresholds_confirm(&messageP->header.transaction_id,&status, &link_cfg_status_list); -} -//----------------------------------------------------------------------------- -void mRALlte_check_thresholds_signal_strength(MIH_C_THRESHOLD_VAL_T new_valP, MIH_C_THRESHOLD_VAL_T old_valP) -{ - //----------------------------------------------------------------------------- - - unsigned int threshold_index, threshold_index_mov; - unsigned int link_index; - unsigned int buffer_index; - MIH_C_THRESHOLD_VAL_T threshold_val; - MIH_C_THRESHOLD_XDIR_T threshold_xdir; - MIH_C_TH_ACTION_T th_action; - LIST(MIH_C_LINK_PARAM_RPT, LinkParametersReportList); - MIH_C_TRANSACTION_ID_T transaction_id; - MIH_C_LINK_TUPLE_ID_T link_identifier; - char buf[256]; - - DEBUG("%s new_val %d old_val %d\n", __FUNCTION__, new_valP, old_valP); - - LinkParametersReportList_list.length = 0; - - for (link_index = 0; - link_index < MIH_C_LINK_CFG_PARAM_LIST_LENGTH; - link_index++) { - - if (ralpriv->active_mih_link_cfg_param_threshold[link_index] == MIH_C_BOOLEAN_TRUE) { - - if ( ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].link_param_type.choice == MIH_C_LINK_PARAM_TYPE_CHOICE_GEN) { - - th_action = ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].th_action; - - for (threshold_index = 0; - threshold_index < ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.length; - threshold_index ++) { - - threshold_val = ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index].threshold_val; - threshold_xdir = ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index].threshold_xdir; - - switch (th_action) { - case MIH_C_SET_NORMAL_THRESHOLD: - if (((threshold_xdir == MIH_C_ABOVE_THRESHOLD) && (old_valP <= threshold_val) && (new_valP > threshold_val)) || - ((threshold_xdir == MIH_C_BELOW_THRESHOLD) && (old_valP >= threshold_val) && (new_valP < threshold_val))) { - - memset(buf, 0, 256); - buffer_index = sprintf(buf, "CROSSED NORMAL THRESHOLD VAL %d DIR ", threshold_val); - buffer_index = MIH_C_THRESHOLD_XDIR2String2(&threshold_xdir, &buf[buffer_index]); - buffer_index = sprintf(buf, " with VAL %d\n", new_valP); - NOTICE("%s", buf); - - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type.choice = MIH_C_LINK_PARAM_TYPE_CHOICE_GEN; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type._union.link_param_gen = MIH_C_LINK_PARAM_GEN_SIGNAL_STRENGTH; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param._union.link_param_val = new_valP; - - LinkParametersReportList_list.val[LinkParametersReportList_list.length].choice = MIH_C_LINK_PARAM_RPT_CHOICE_THRESHOLD; - LinkParametersReportList_list.val[LinkParametersReportList_list.length]._union.threshold.threshold_val = threshold_val; - LinkParametersReportList_list.val[LinkParametersReportList_list.length]._union.threshold.threshold_xdir = threshold_xdir; - LinkParametersReportList_list.length = LinkParametersReportList_list.length + 1; - } - - break; - - case MIH_C_SET_ONE_SHOT_THRESHOLD: - if (((threshold_xdir == MIH_C_ABOVE_THRESHOLD) && (old_valP <= threshold_val) && (new_valP > threshold_val)) || - ((threshold_xdir == MIH_C_BELOW_THRESHOLD) && (old_valP >= threshold_val) && (new_valP < threshold_val))) { - - memset(buf, 0, 256); - buffer_index = sprintf(buf, "CROSSED ONE SHOT THRESHOLD VAL %d DIR ", threshold_val); - buffer_index = MIH_C_THRESHOLD_XDIR2String2(&threshold_xdir, &buf[buffer_index]); - buffer_index = sprintf(buf, " with VAL %d\n", new_valP); - NOTICE("%s", buf); - - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type.choice = MIH_C_LINK_PARAM_TYPE_CHOICE_GEN; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.link_param_type._union.link_param_gen = MIH_C_LINK_PARAM_GEN_SIGNAL_STRENGTH; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param.choice = MIH_C_LINK_PARAM_CHOICE_LINK_PARAM_VAL; - LinkParametersReportList_list.val[LinkParametersReportList_list.length].link_param._union.link_param_val = new_valP; - - LinkParametersReportList_list.val[LinkParametersReportList_list.length].choice = MIH_C_LINK_PARAM_RPT_CHOICE_THRESHOLD; - LinkParametersReportList_list.val[LinkParametersReportList_list.length]._union.threshold.threshold_val = threshold_val; - LinkParametersReportList_list.val[LinkParametersReportList_list.length]._union.threshold.threshold_xdir = threshold_xdir; - LinkParametersReportList_list.length = LinkParametersReportList_list.length + 1; - - // Remove this threshold: shift Thresholds - for (threshold_index_mov = threshold_index; - threshold_index_mov < ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.length - 1; - threshold_index_mov ++) { - memcpy(&ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index_mov], - &ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index_mov+1], - sizeof(MIH_C_THRESHOLD_T)); - } - } - - break; - - // may be not necessary here - case MIH_C_CANCEL_THRESHOLD: - - // shift Thresholds - for (threshold_index_mov = threshold_index; - threshold_index_mov < ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.length - 1; - threshold_index_mov ++) { - memcpy(&ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index_mov], - &ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.val[threshold_index_mov+1], - sizeof(MIH_C_THRESHOLD_T)); - } - - ralpriv->mih_link_cfg_param_thresholds_list.val[link_index].threshold_list.length -= 1; - break; - - default: - ERR("%s UNKNOWN TH ACTION FOUND, RETURN", __FUNCTION__); - return; - } - } - } - } - } - - if (LinkParametersReportList_list.length > 0) { - transaction_id = MIH_C_get_new_transaction_id(); - - link_identifier.link_id.link_type = MIH_C_WIRELESS_UMTS; - link_identifier.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR; - MIH_C_3GPP_ADDR_set(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP, strlen(DEFAULT_ADDRESS_3GPP)); - link_identifier.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL; - - mRALlte_send_link_parameters_report_indication(&transaction_id, - &link_identifier, - &LinkParametersReportList_list); - } -} \ No newline at end of file diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/nasRGdummy.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/nasRGdummy.c deleted file mode 100644 index 6df6fe19a5..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/nasRGdummy.c +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#include <stdio.h> - - -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include "nas_rg_netlink.h" - -//int state, cell_id; -//int rb_id; - -int NAS_TQAL_sock_connect(void) -{ - struct sockaddr_un remote; - int len,s; - - if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - perror("NAS_TQAL_sock_connect - socket"); - exit(1); - } - - printf("Trying to connect...\n"); - remote.sun_family = AF_UNIX; - strcpy(remote.sun_path, SOCK_TQAL_NAS_PATH); - len = strlen(remote.sun_path) + sizeof(remote.sun_family); - - if (connect(s, (struct sockaddr *)&remote, len) == -1) { - perror("NAS_TQAL_sock_connect - connect() failed"); - exit(1); - } - - printf("Connected to TQAL.\n"); - return s; -} - -int NAS_TQALreceive(int s) -{ - char str1[NAS_RG_NETL_MAXLEN]; - char str2[NAS_RG_NETL_MAXLEN]; - int t, done; - int ix; - struct nas_rg_netl_request *msgToRcve; - struct nas_rg_netl_reply *msgToSend; - - done = 0; - t = recv(s, str1, NAS_RG_NETL_MAXLEN, 0); - - if (t <= 0) { - if (t < 0) perror("NAS_TQALreceive : recv() failed"); - - done = 1; - } - - printf("message from TQAL, length: %d\n", t); - - msgToRcve = (struct nas_rg_netl_request *) str1; - msgToSend = (struct nas_rg_netl_reply *) str2; - memset(str2, 0, NAS_RG_NETL_MAXLEN); - - switch (msgToRcve->type) { - case NAS_RG_MSG_RB_ESTABLISH_REQUEST: - printf("NAS_RG_MSG_RB_ESTABLISH_REQUEST received\n"); - msgToSend->type = NAS_RG_MSG_RB_ESTABLISH_REPLY; - msgToSend->length = sizeof(struct nas_rg_netl_hdr)+sizeof(struct nas_rg_msg_rb_establish_reply); - msgToSend->tqalNASPrimitive.rb_est_rep.cnxid = msgToRcve->tqalNASPrimitive.rb_est_req.cnxid; - ix = (msgToRcve->tqalNASPrimitive.rb_est_req.cnxid-1) % 32; - msgToSend->tqalNASPrimitive.rb_est_rep.ue_id = (msgToRcve->tqalNASPrimitive.rb_est_req.cnxid - ix - 1)/32; - msgToSend->tqalNASPrimitive.rb_est_rep.RBParms.rbId = msgToRcve->tqalNASPrimitive.rb_est_req.RBParms.rbId; - msgToSend->tqalNASPrimitive.rb_est_rep.RBParms.QoSclass = msgToRcve->tqalNASPrimitive.rb_est_req.RBParms.QoSclass; - msgToSend->tqalNASPrimitive.rb_est_rep.RBParms.dscp = msgToRcve->tqalNASPrimitive.rb_est_req.RBParms.dscp; - msgToSend->tqalNASPrimitive.rb_est_rep.result = NAS_CONNECTED; - printf("Establishing Radio Bearer - cnx_id %d, Rb_id %d , QoSclass %d, dscp %d\n\n", - msgToSend->tqalNASPrimitive.rb_est_rep.cnxid , - msgToSend->tqalNASPrimitive.rb_est_rep.RBParms.rbId , - msgToSend->tqalNASPrimitive.rb_est_rep.RBParms.QoSclass, - msgToSend->tqalNASPrimitive.rb_est_rep.RBParms.dscp ); - break; - - case NAS_RG_MSG_RB_RELEASE_REQUEST: - printf("NAS_RG_MSG_RB_RELEASE_REQUEST received\n"); - msgToSend->type = NAS_RG_MSG_RB_RELEASE_REPLY; - msgToSend->length = sizeof(struct nas_rg_netl_hdr)+sizeof(struct nas_rg_msg_rb_release_reply); - msgToSend->tqalNASPrimitive.rb_rel_rep.cnxid = msgToRcve->tqalNASPrimitive.rb_rel_req.cnxid; - msgToSend->tqalNASPrimitive.rb_rel_rep.ue_id = msgToRcve->tqalNASPrimitive.rb_rel_req.ue_id; - msgToSend->tqalNASPrimitive.rb_rel_rep.result = NAS_DISCONNECTED; - printf("Releasing Radio Bearer - cnx_id %d, ue_id %d\n\n", - msgToSend->tqalNASPrimitive.rb_rel_rep.cnxid, - msgToSend->tqalNASPrimitive.rb_rel_rep.ue_id); - break; - - case NAS_RG_MSG_MT_MCAST_JOIN: - printf("NAS_RG_MSG_MT_MCAST_JOIN received\n"); - msgToSend->type = NAS_RG_MSG_MT_MCAST_JOIN_REP; - msgToSend->length = sizeof(struct nas_rg_netl_hdr)+sizeof(struct nas_rg_msg_mt_mcast_join_rep); - msgToSend->tqalNASPrimitive.mt_mc_join_rep.cnxid = msgToRcve->tqalNASPrimitive.mt_mcast_join.cnxid; - msgToSend->tqalNASPrimitive.mt_mc_join_rep.ue_id = msgToRcve->tqalNASPrimitive.mt_mcast_join.ue_id; - msgToSend->tqalNASPrimitive.mt_mc_join_rep.result = NAS_CONNECTED; - printf("MT Joining Multicast - cnx_id %d, ue_id %d\n\n", - msgToSend->tqalNASPrimitive.mt_mc_join_rep.cnxid, - msgToSend->tqalNASPrimitive.mt_mc_join_rep.ue_id); - break; - - case NAS_RG_MSG_MT_MCAST_LEAVE: - printf("NAS_RG_MSG_MT_MCAST_LEAVE received\n"); - msgToSend->type = NAS_RG_MSG_MT_MCAST_LEAVE_REP; - msgToSend->length = sizeof(struct nas_rg_netl_hdr)+sizeof(struct nas_rg_msg_mt_mcast_leave_rep); - msgToSend->tqalNASPrimitive.mt_mc_leavce_rep.cnxid = msgToRcve->tqalNASPrimitive.mt_mcast_leave.cnxid; - msgToSend->tqalNASPrimitive.mt_mc_leavce_rep.ue_id = msgToRcve->tqalNASPrimitive.mt_mcast_leave.ue_id; - msgToSend->tqalNASPrimitive.mt_mc_leavce_rep.result = NAS_DISCONNECTED; - printf("MT Leaving Multicast - cnx_id %d, ue_id %d\n\n", - msgToSend->tqalNASPrimitive.mt_mc_leavce_rep.cnxid, - msgToSend->tqalNASPrimitive.mt_mc_leavce_rep.ue_id); - break; - - case NAS_RG_MSG_CNX_STATUS_REQUEST: - printf("NAS_RG_MSG_CNX_STATUS_REQUEST received\n"); - break; - - case NAS_RG_MSG_RB_LIST_REQUEST: - printf("NAS_RG_MSG_RB_LIST_REQUEST received\n"); - break; - - case NAS_RG_MSG_STATISTIC_REQUEST: - printf("NAS_RG_MSG_STATISTIC_REQUEST received\n"); - break; - - case NAS_RG_MSG_MEASUREMENT_REQUEST: - printf("NAS_RG_MSG_MEASUREMENT_REQUEST received\n"); - break; - - default: - printf ("Invalid message Type %d\n",msgToRcve->type); - break; - } - - if (send(s, str2, msgToSend->length, 0) < 0) { - perror("NAS_TQALreceive : send() failed"); - done = 1; - } - - printf ("message sent to TQAL %d\n",msgToSend->length); - - return done; - -} - -int main(void) -{ - int s_ral, rc, done; - fd_set readfds; - struct timeval tv; - - /* Connect to the RAL-LTE */ - do { - s_ral = NAS_TQAL_sock_connect(); - - if (s_ral <= 0) { - sleep(2); - } - } while (s_ral < 0); - - done = 0; - - do { - // Create fd_set and wait for input - FD_ZERO(&readfds); - FD_SET (s_ral, &readfds); - tv.tv_sec = 0; - tv.tv_usec = 100000; // timeout select for 100ms and read FIFOs - - rc = select(FD_SETSIZE, &readfds, NULL, NULL, &tv); - - if (rc ==-1) { - perror("main : select() failed"); - done = 1; - } - - // something received ! - if (rc >= 0) { - if (FD_ISSET(s_ral, &readfds)) { - done = NAS_TQALreceive(s_ral); - } - } - - } while (!done); - - close(s_ral); - - return 0; -} diff --git a/openair3/RAL-LTE/RAL-DUMMY/SRC/nasUEdummy.c b/openair3/RAL-LTE/RAL-DUMMY/SRC/nasUEdummy.c deleted file mode 100755 index 30bfe48cce..0000000000 --- a/openair3/RAL-LTE/RAL-DUMMY/SRC/nasUEdummy.c +++ /dev/null @@ -1,464 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can 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. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ -#include <stdio.h> - -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <netdb.h> -#include <sys/time.h> -#include <ctype.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include "nas_ue_netlink.h" - -#define CONF_NASUE_DUMMY -#define CONF_UNKNOWN_CELL_ID 0 - -#include "nasUE_config.h" - -int state, cell_id; - -#define MEAS_MAX_RSSI 110 - - -#ifdef MIH_USER_CONTROL -char *g_mih_user_ip_address = MIH_USER_IP_ADDRESS; -char *g_mih_user_remote_port = MIH_USER_REMOTE_PORT; -char *g_nas_ip_address = NAS_IP_ADDRESS; -char *g_nas_listening_port_for_mih_user = NAS_LISTENING_PORT_FOR_MIH_USER; -int g_sockd_mih_user; -signed int g_mih_user_rssi_increment = 0; -//--------------------------------------------------------------------------- -int NAS_mihuser_connect(void) -{ - //--------------------------------------------------------------------------- - struct addrinfo hints; - struct addrinfo *result, *rp; - int s, on; - struct sockaddr_in *addr = NULL; - struct sockaddr_in6 *addr6 = NULL; - unsigned char buf[sizeof(struct sockaddr_in6)]; - - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ - hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ - hints.ai_flags = 0; - hints.ai_protocol = 0; /* Any protocol */ - - s = getaddrinfo(g_mih_user_ip_address, g_mih_user_remote_port, &hints, &result); - - if (s != 0) { - printf("ERR getaddrinfo: %s\n", gai_strerror(s)); - return -1; - } - - /* getaddrinfo() returns a list of address structures. - Try each address until we successfully connect(2). - If socket(2) (or connect(2)) fails, we (close the socket - and) try the next address. */ - - for (rp = result; rp != NULL; rp = rp->ai_next) { - g_sockd_mih_user = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - - if (g_sockd_mih_user == -1) - continue; - - on = 1; - setsockopt( g_sockd_mih_user, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - - if(rp->ai_family == AF_INET) { - printf("Destination address %s is an ipv4 address\n",g_mih_user_ip_address); - addr = (struct sockaddr_in *)(&buf[0]); - addr->sin_port = htons(atoi(g_nas_listening_port_for_mih_user)); - addr->sin_family = AF_INET; - s = inet_pton(AF_INET, g_nas_ip_address, &addr->sin_addr); - - if (s <= 0) { - if (s == 0) { - printf("ERR IP NAS address should be a IPv4 ADDR - But found not in presentation format : %s\n", g_nas_ip_address); - } else { - printf("ERR %s - inet_pton(NAS IPv4 ADDR %s): %s\n", __FUNCTION__, g_nas_ip_address, strerror(s)); - } - - return -1; - } - - s = bind(g_sockd_mih_user, (const struct sockaddr *)addr, sizeof(struct sockaddr_in)); - - if (s == -1) { - printf("ERR NAS IPv4 Address Bind: %s\n", strerror(errno)); - return -1; - } - - // sockd_mihf is of type SOCK_DGRAM, rp->ai_addr is the address to which datagrams are sent by default - if (connect(g_sockd_mih_user, rp->ai_addr, rp->ai_addrlen) != -1) { - printf(" NAS is now UDP-CONNECTED to MIH-F\n"); - return 0; - } else { - close(g_sockd_mih_user); - } - } else if (rp->ai_family == AF_INET6) { - printf("Destination address %s is an ipv6 address\n",g_mih_user_ip_address); - addr6 = (struct sockaddr_in6 *)(&buf[0]); - addr6->sin6_port = htons(atoi(g_nas_listening_port_for_mih_user)); - addr6->sin6_family = AF_INET6; - s = inet_pton(AF_INET, g_nas_ip_address, &addr6->sin6_addr); - - if (s <= 0) { - if (s == 0) { - printf("ERR IP NAS address should be a IPv6 ADDR, But found not in presentation format : %s\n", g_nas_ip_address); - } else { - printf("ERR %s - inet_pton(NAS IPv6 ADDR %s): %s\n", __FUNCTION__, g_nas_ip_address, strerror(s)); - } - - return -1; - } - - s = bind(g_sockd_mih_user, (const struct sockaddr *)addr6, sizeof(struct sockaddr_in)); - - if (s == -1) { - printf("ERR NAS IPv6 Address Bind: %s\n", strerror(errno)); - return -1; - } - - if (connect(g_sockd_mih_user, rp->ai_addr, rp->ai_addrlen) != -1) { - printf(" NAS is now able to receive UDP control messages from MIH-User\n"); - return 0; - } else { - close(g_sockd_mih_user); - } - } else { - printf("ERR %s is an unknown address format %d\n",g_mih_user_ip_address,rp->ai_family); - } - - close(g_sockd_mih_user); - } - - if (rp == NULL) { /* No address succeeded */ - printf("ERR Could not establish socket to MIH-User\n"); - return -1; - } - - return -1; -} - -int NAS_MIHUSERreceive(int sock) -{ - unsigned char str[NAS_UE_NETL_MAXLEN]; - int t, done; - t=recv(sock, str, NAS_UE_NETL_MAXLEN, 0); - - if (t <= 0) { - if (t < 0) perror("NAS_MIHUSERreceive : recv"); - - done = 1; - } - - printf("\nmessage from MIH-USER, length: %d\n", t); - - switch (str[0]) { - case 0xff: - printf("MIH-USER ASK FOR DECREASING RSSI\n"); - g_mih_user_rssi_increment = -RSSI_INCREMENT_STEP; - break; - - case 0x00: - printf("MIH-USER ASK FOR NOT MODIFYING RSSI\n"); - g_mih_user_rssi_increment = 0; - break; - - case 0x01: - printf("MIH-USER ASK FOR INCREASING RSSI\n"); - g_mih_user_rssi_increment = RSSI_INCREMENT_STEP; - break; - - default: - printf("received %hx\n", str[0]); - return -1; - } - - return 0; -} -#endif -int NAS_IAL_sock_connect(void) -{ - struct sockaddr_un remote; - int len,s; - - if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - perror("NAS_IALconnect - socket"); - exit(1); - } - - printf("Trying to connect...\n"); - remote.sun_family = AF_UNIX; - strcpy(remote.sun_path, SOCK_NAS_PATH); - len = strlen(remote.sun_path) + sizeof(remote.sun_family); - - if (connect(s, (struct sockaddr *)&remote, len) == -1) { - perror("NAS_IALconnect - connect"); - return -1; - } - - printf("Connected.\n"); - return s; -} - - -int NAS_IALreceive(int s) -{ - char str1[NAS_UE_NETL_MAXLEN]; - char str2[NAS_UE_NETL_MAXLEN]; - int i, t, done; - struct nas_ue_netl_request *msgToRcve; - struct nas_ue_netl_reply *msgToSend; - - done =0; - t=recv(s, str1, NAS_UE_NETL_MAXLEN, 0); - - if (t <= 0) { - if (t < 0) perror("RAL_process_command : recv"); - - done = 1; - } - - printf("\nmessage from RAL, length: %d\n", t); - - msgToRcve = (struct nas_ue_netl_request *) str1; - msgToSend = (struct nas_ue_netl_reply *) str2; - memset(str2,0,NAS_UE_NETL_MAXLEN); - - switch (msgToRcve->type) { - case NAS_UE_MSG_CNX_ESTABLISH_REQUEST: - printf("NAS_UE_MSG_CNX_ESTABLISH_REQUEST received\n"); - msgToSend->type = NAS_UE_MSG_CNX_ESTABLISH_REPLY; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+sizeof(struct nas_ue_msg_cnx_establish_reply); - msgToSend->ialNASPrimitive.cnx_est_rep.status = NAS_CONNECTED; - state = NAS_CONNECTED; - cell_id = msgToRcve->ialNASPrimitive.cnx_req.cellid; - break; - - case NAS_UE_MSG_CNX_RELEASE_REQUEST: - printf("NAS_UE_MSG_CNX_RELEASE_REQUEST received\n"); - msgToSend->type = NAS_UE_MSG_CNX_RELEASE_REPLY; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+sizeof(struct nas_ue_msg_cnx_release_reply); - msgToSend->ialNASPrimitive.cnx_rel_rep.status = NAS_DISCONNECTED; - state = NAS_DISCONNECTED; - cell_id = CONF_UNKNOWN_CELL_ID; - break; - - case NAS_UE_MSG_CNX_LIST_REQUEST: - printf("NAS_UE_MSG_CNX_LIST_REQUEST received\n"); - msgToSend->type = NAS_UE_MSG_CNX_LIST_REPLY; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+sizeof(struct nas_ue_msg_cnx_list_reply); - msgToSend->ialNASPrimitive.cnx_list_rep.state = state; - msgToSend->ialNASPrimitive.cnx_list_rep.cellid = cell_id; - msgToSend->ialNASPrimitive.cnx_list_rep.iid4 = CONF_iid4; - msgToSend->ialNASPrimitive.cnx_list_rep.iid6[0] = conf_iid6_0[CONF_MT0]; - msgToSend->ialNASPrimitive.cnx_list_rep.iid6[1] = conf_iid6_1[CONF_MT0]; - - if (state == NAS_CONNECTED) { - msgToSend->ialNASPrimitive.cnx_list_rep.num_rb = CONF_num_rb; - msgToSend->ialNASPrimitive.cnx_list_rep.nsclassifier = CONF_num_rb; - } - - break; - - case NAS_UE_MSG_CNX_STATUS_REQUEST: - printf("NAS_UE_MSG_CNX_STATUS_REQUEST received\n"); - msgToSend->type = NAS_UE_MSG_CNX_STATUS_REPLY; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+sizeof(struct nas_ue_msg_cnx_status_reply); - msgToSend->ialNASPrimitive.cnx_stat_rep.status = state; - msgToSend->ialNASPrimitive.cnx_stat_rep.cellid = cell_id; - - if (state == NAS_CONNECTED) { - msgToSend->ialNASPrimitive.cnx_stat_rep.num_rb = CONF_num_rb; - msgToSend->ialNASPrimitive.cnx_stat_rep.signal_level = conf_level[0]; - } - - break; - - case NAS_UE_MSG_RB_LIST_REQUEST: - printf("NAS_UE_MSG_RB_LIST_REQUEST received\n"); - msgToSend->type = NAS_UE_MSG_RB_LIST_REPLY; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+sizeof(struct nas_ue_msg_rb_list_reply); - - if (state == NAS_CONNECTED) { - msgToSend->ialNASPrimitive.rb_list_rep.num_rb = CONF_num_rb; - - for (i=0; i<CONF_num_rb; i++) { - msgToSend->ialNASPrimitive.rb_list_rep.RBList[i].rbId = conf_rbId[i]; - msgToSend->ialNASPrimitive.rb_list_rep.RBList[i].QoSclass = conf_qoSclass[i]; - msgToSend->ialNASPrimitive.rb_list_rep.RBList[i].dscp = conf_dscp[i]; - } - } - - break; - - case NAS_UE_MSG_STATISTIC_REQUEST: - printf("NAS_UE_MSG_STATISTIC_REQUEST received\n"); - msgToSend->type = NAS_UE_MSG_STATISTIC_REPLY; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+sizeof(struct nas_ue_msg_statistic_reply); - - if (state == NAS_CONNECTED) { - msgToSend->ialNASPrimitive.statistics_rep.rx_packets = CONF_rx_packets; - msgToSend->ialNASPrimitive.statistics_rep.tx_packets = CONF_tx_packets; - msgToSend->ialNASPrimitive.statistics_rep.rx_bytes = CONF_rx_bytes; - msgToSend->ialNASPrimitive.statistics_rep.tx_bytes = CONF_tx_bytes; - msgToSend->ialNASPrimitive.statistics_rep.rx_errors = CONF_rx_errors; - msgToSend->ialNASPrimitive.statistics_rep.tx_errors = CONF_tx_errors; - msgToSend->ialNASPrimitive.statistics_rep.rx_dropped = CONF_rx_dropped; - msgToSend->ialNASPrimitive.statistics_rep.tx_dropped = CONF_tx_dropped; - } - - break; - - case NAS_UE_MSG_MEAS_REQUEST: - printf("NAS_UE_MSG_MEAS_REQUEST received\n"); - msgToSend->type = NAS_UE_MSG_MEAS_REPLY; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+sizeof(struct nas_ue_msg_measure_reply); - msgToSend->ialNASPrimitive.meas_rep.num_cells = CONF_num_cells; - printf("\tSignal levels sent "); - - for (i=0; i<CONF_num_rb; i++) { -#ifdef MIH_USER_CONTROL - - // LG TEST WITH ONLY i =0 - if (i == 0) { - conf_level[i] += g_mih_user_rssi_increment; - - if (conf_level[i] > MEAS_MAX_RSSI) conf_level[i] = MEAS_MAX_RSSI; - - if (conf_level[i] < 0) conf_level[i] = 0; - } - -#endif - msgToSend->ialNASPrimitive.meas_rep.measures[i].cell_id = conf_cell_id[i]; - msgToSend->ialNASPrimitive.meas_rep.measures[i].level = conf_level[i]; - msgToSend->ialNASPrimitive.meas_rep.measures[i].provider_id = conf_provider_id[i]; - printf ("| cell %d : %d ", conf_cell_id[i], conf_level[i]); - } - - printf("\n"); - break; - - case NAS_UE_MSG_IMEI_REQUEST: - printf("NAS_UE_MSG_IMEI_REQUEST received\n"); - msgToSend->type = NAS_UE_MSG_IMEI_REPLY; - msgToSend->length = sizeof(struct nas_ue_netl_hdr)+sizeof(struct nas_ue_l2id_reply); - msgToSend->ialNASPrimitive.l2id_rep.l2id[0] = conf_iid6_0[CONF_MT0]; - msgToSend->ialNASPrimitive.l2id_rep.l2id[1] = conf_iid6_1[CONF_MT0]; - state = NAS_DISCONNECTED; - cell_id = CONF_UNKNOWN_CELL_ID; - break; - - default: - printf ("Invalid message Type %d\n",msgToRcve->type); - } - - if (send(s, str2, msgToSend->length, 0) < 0) { - perror("IAL_process_command : send"); - done = 1; - } - - printf ("Response message sent to RAL %d\n",msgToSend->length); - - return done; - -} - -int main(void) -{ - int s = 0; - int rc, done; - fd_set readfds; - struct timeval tv; - - do { - s= NAS_IAL_sock_connect(); - - if (s <= 0) { - sleep(2); - } - } while (s < 0); - -#ifdef MIH_USER_CONTROL - NAS_mihuser_connect(); -#endif - - done = 0; - - do { - // Create fd_set and wait for input - FD_ZERO(&readfds); - FD_SET (s, &readfds); -#ifdef MIH_USER_CONTROL - FD_SET (g_sockd_mih_user, &readfds); -#endif - tv.tv_sec = 0; - tv.tv_usec = 100000; // timeout select for 100ms and read FIFOs - - rc = select(FD_SETSIZE, &readfds, NULL, NULL, &tv); - - if (rc ==-1) { - perror("select"); - done = 1; - } - - // something received ! - if (rc>=0) { - if (FD_ISSET(s,&readfds)) { - done = NAS_IALreceive(s); - } - -#ifdef MIH_USER_CONTROL - - if (FD_ISSET(g_sockd_mih_user,&readfds)) { - done = NAS_MIHUSERreceive(g_sockd_mih_user); - } - -#endif - } - - } while (!done); - - - close(s); - - return 0; -} - - diff --git a/openair3/RAL-LTE/RAL-LTE.readme.txt b/openair3/RAL-LTE/RAL-LTE.readme.txt deleted file mode 100644 index 87fad4b6ef..0000000000 --- a/openair3/RAL-LTE/RAL-LTE.readme.txt +++ /dev/null @@ -1,113 +0,0 @@ -Doc updated on 13/05/2013 - -README file for LTE_LINK_SAP - - ****************** - Release dates - - D0.1 : 13/05/2013 (RAL_UE only) - ****************** - - Content - 1. Install odtone on ubuntu - 2. Test RAL-Dummy - 3. Install and run LTE-RAL-UE - - ****************** - 1. Install odtone on ubuntu - - A. Download Boost v1.48 + ODTONE (Medieval Version) in a directory named myDir for example - - B. unzip both files, creating folders boost_1_48_0 and odtone - - C. Compile boost.build - > cd myDir/boost_1_48_0/tools/build/v2 - > ./bootstrap.sh - > sudo ./b2 install - - D. Compile ODTONE - > cd myDir/odtone - > b2 - ==> this creates odtone-mihf and miis executables in the myDir/odtone/dist directory and copies odtone.conf in that same directory - - E. Test Local demo - 1- compile mih user - > cd myDir/odtone/app/cm_demo1 - > b2 - ==> this creates cm_demo1 executable in the myDir/odtone/dist directory and copies mih_usr.conf in that same directory - 2- compile Link sap - > cd myDir/odtone/app/link_sap - > b2 - ==> this creates link_sap executable in the myDir/odtone/dist directory and copies link_sap.conf in that same directory - 3- check configuration files and update if needed (see ODTONE doc) - 4- open 3 terminals in the odtone/dist directory, each one for running an executable in the following order - T1 : > ./odtone-mihf - T2 : > ./link_sap - T3 : > ./cm_demo1 - - ****************** - 2. Test RAL-Dummy - - A. Install LTE user - copy the LTE user folder from openair3/RAL-LTE/RAL-DUMMY/802.21-SCENARIO/VERSION0 to the app directory - > b2 linkflags=-lrt - - B. Compile the RAL-Dummy - > cd <oai-dir>/openair3/RAL-LTE/RAL-DUMMY - > make - ==> this creates several executables: - - mRALlteDummy + NASUEdummy for the UE - - eRALlteDummy + NASRGdummy for the eNB - A small tool to trigger action on NASUEdummy is provided in RAL-DUMMY/802.21-SCENARIO : "sendUDP-01" and "sendUDP-FF" (see below) - - C. Execute RAL-UE simulation - - note : path1 = myDir/odtone, path2 = <oai-dir>/openair3/RAL-LTE - - Requires 5 terminals started in the following order (next step = create scripts) - - T1 > cd path1/dist - > ./odtone-mihf --log=4 - - T2 > cd path2/RAL-DUMMY - > ./mRALlteDummy -c - - T3 > cd path2/RAL-DUMMY - > ./NASUEdummy - - T4 > cd path1/dist - > ./lte_user - - T5 > cd path2/RAL-DUMMY/802.21-SCENARIO - When USER receives MIH_Link_Get_Parameters_confirm - > sendUDP-01 - ==> this tests link detection and activation - When USER receives the second MIH_Link_Actions.confirm - > sendUDP-FF - ==> this tests link parameters report going down and de-activation - -****************** - 3. Install and run LTE-RAL-UE - - A. Install LTE user - copy the lte_test_user folder from openair3/RAL-LTE/LTE_RAL_UE/MIH-USER to the app directory of ODTONE - > b2 linkflags=-lrt - - B. Compile the LTE_RAL_UE - > cd <oai-dir>/openair3/RAL-LTE/LTE_RAL_UE - > make - ==> this creates the LTE_RAL_UE executable - - C. Run the LTE_RAL_UE - - note : path1 = myDir/odtone, path2 = <oai-dir>/openair3/RAL-LTE - - Requires 3 terminals started in the following order (next step = create scripts) - - start OAI platform in CELLULAR mode - - T1 > cd path1/dist - > ./odtone-mihf --log=4 - - T2 > cd path2/LTE_RAL_UE - > ./LTE_RAL_UE - - T3 > cd path1/dist - > ./lte_user - - - - - - -- GitLab